【问题标题】:Replace string to the target format将字符串替换为目标格式
【发布时间】:2015-06-03 10:42:55
【问题描述】:

有没有办法使用regex 或字符串替换来替换字符串

COND X > 49 300000 200000

预期的格式是

COND(X > 49,300000,200000)

我目前的方法是做string.Split(" ") 并将其转换为列表并在适当的索引处插入大括号。但我的方法的问题是字符串不是独立的,而是包含在更大的表达式中,有时与whitespace 进行比较,如COND ABC =。条件的右侧是一个空格。

【问题讨论】:

  • 您使用的是哪种 .NET 语言?

标签: .net regex vb.net string replace


【解决方案1】:

不可能一次完成。我建议:

  1. 添加括号:(\p{Lu}+)\s*(\p{Lu}+)(.*)(替换为$1($2$3))

见demo

  1. 然后,您可以使用正则表达式查找数字之间的所有空格并将其替换为逗号:(?<=\d+)\s+(?=\d+)。

见demo(见上下文标签)。

这是一个有效的 VB.NET 代码:

Dim strIn As String = "COND X > 49 300000 200000"
Dim rx2 = New Regex("(\p{Lu}+)\s*(\p{Lu}+)(.*)")
Dim result2 As String = rx2.Replace(strIn, "$1($2$3)")
result2 = Regex.Replace(result2, "(?<=\d+)\s+(?=\d+)", ",")

输出:

编辑:1-REGEX PASS:

如果您在Regex.Replace 中使用MatchEvaluator 函数,我们可以确保只运行一次正则表达式。

Dim str3 = "COND X > 49 300000 200000 778888"
    Dim rx3 = New Regex("(\p{Lu}+)\s*(\p{Lu}+.*?)(?:\s+(\d+))+")
    Dim result2 = rx3.Replace(str3, New MatchEvaluator(Function(m As Match)
                        If m.Groups(3).Captures.Count > 0 Then
                             Return String.Format("{0}({1} {2})",
                                               m.Groups(1).Value,
                                               m.Groups(2).Value,
                                               String.Join(",",
                                                            m.Groups(3).Captures.Cast(Of Capture)().Select(Function(n) n.Value).ToArray()
                                                           )
                                               )
                         Else
                             Return m.Value
                         End If
                         End Function))

结果:

【讨论】:

  • 太好了,如果您觉得我的回答有帮助,也请考虑点赞。
【解决方案2】:

在您的 RegularExpression 中设置您的捕获组,并在组之间粘贴适当的分隔符。

注意:这仅适用于您想要在 3 组数字之间添加逗号的情况。

Imports System
Imports System.Text.RegularExpressions

Module Module1
    Sub Main()
        Dim str As String = "COND X < 49 300000 200000"
        '^ Beginning of the line
        '([A-Z]+)\s* capture group 1 that will have any capital letters before the first space,
        '  but the space is not included in the group
        '([A-Z]\s*..?\s*) capture group 2 that will have X (or any single capital letter) plus
        '  a space, then any character plus a possible character (<=), then a space
        '(\d+)\s* capture group 3 & 4 that will have the first group of digits plus a space, but 
        '  the space is not included in the group
        '(\d+)$ capture group 5 that will have the last group of digits. $ End of line
        Dim pattern As String = "^([A-Z]+)\s*([A-Z]\s*..?\s*)(\d+)\s*(\d+)\s*(\d+)$"
        Console.WriteLine(Regex.Replace(str, pattern, "$1($2$3,$4,$5)"))
        Console.ReadLine()
    End Sub
End Module

结果:

COND(X > 49,300000,200000)

更新

如果您要处理多于三组数字,则使用 Regex.Match 并构建您的字符串允许一次通过。

Imports System
Imports System.Text.RegularExpressions

Module Module1
    Sub Main()
        Dim str As String = "COND X >= 49 300000 200000 123456 456789"
        '([A-Z]+)\s* capture group 1 that will have any capital letters before the first space,
        '  but the space is not included in the group
        '([A-Z]\s*..?\s*) capture group 2 that will have X (or any single capital letter) plus
        '  a space, then any character plus a possible character (<=), then a space
        '(.+)\s* capture group 3 that will have the sets of digits with spaces in between
        Dim pattern As String = "([A-Z]+)\s*([A-Z]\s*..?\s*)(.+)"
        Dim groups As GroupCollection = Regex.Match(str, pattern).Groups
        Console.WriteLine("{0}({1}{2})", groups(1), groups(2), groups(3).Value.Replace(" ", ","))
        Console.ReadLine()
    End Sub
End Module

结果:

COND(X >= 49,300000,200000,123456,456789)

【讨论】:

  • 很酷,但是您如何知道输入字符串中的数字组数量?如果有4个:123 223 3456 4567呢?当然,从问题中并不清楚,但为了更安全并且不影响\G 运算符的性能,我们最好使用 2-pass 方法。但是,有一种正则表达式方法,我会更新我的答案。
  • @stribizhev 我在一个注释中提到它只适用于 3 组数字。更新的答案捕获 3 个组并重建结果。
【解决方案3】:

您可以使用以下正则表达式进行检测:

(.*)(\w\s?>[\s\d]+)

以下是替换:

$1\($2\)

【讨论】:

    猜你喜欢
    • 2015-09-23
    • 2018-03-26
    • 1970-01-01
    • 2012-03-08
    • 2015-01-21
    • 2015-11-14
    • 2018-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多