Reputation: 68
Is there a way to replace a string using regex
or string replace
COND X > 49 300000 200000
The expected format is
COND(X > 49,300000,200000)
My current approach is to do string.Split(" ")
and convert it to list and insert the braces at the proper indexes. But the problem with my approach is the string is not standalone but is included in a larger expression and also sometimes the comparison happens with whitespace
as in COND ABC =
. The right side of the condition is a whitespace.
Upvotes: 2
Views: 94
Reputation: 107287
You can use following regex for detect :
(.*)(\w\s?>[\s\d]+)
and following for replace :
$1\($2\)
Upvotes: 1
Reputation: 626748
It is impossible to achieve in a single pass. I suggest:
(\p{Lu}+)\s*(\p{Lu}+)(.*)
(replace with $1($2$3)
)See demo
(?<=\d+)\s+(?=\d+)
.See demo (see Context tab).
Here is a working VB.NET code:
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+)", ",")
Output:
EDIT: 1-REGEX PASS:
If you use a MatchEvaluator
function inside Regex.Replace
, we can make sure we only run regex once.
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))
Result:
Upvotes: 2
Reputation: 9041
Setup your capture groups in your RegularExpression
and just stick the appropriate delimiters between the groups.
NOTE: This only works if you have 3 sets of digits you want to stick commas in between.
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
Results:
COND(X > 49,300000,200000)
If you're dealing with more than three sets of digits, then using Regex.Match and building your string allows one pass through.
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
Results:
COND(X >= 49,300000,200000,123456,456789)
Upvotes: 2