How do I replace the nth regex group with a new String in .net?
I have a pipe delimited string like this:
blah|blah|blah|blah|blah|blah|blah|blah|blah|oldDate|blah|blah|
I would like replace the content of the 10th section with a new Date. I am able to match the the old date with the the following code:
'create a group with the first 9 non-pipes followed by a pipe, a group with the old date followed by a pipe, and sub-group of just the old date.
Dim开发者_C百科 pipeRegEx As New RegularExpressions.Regex("(([^\|]*\|){9})(([^\|]*)\|)")
'the sub-group is the 4th group ordinal in the match GroupCollection
Dim oldDate as String=pipeRegEx.Match(strMessage).Groups(4).Value
However, I can't figure out how to repace that group with new text. I have tried:
pipeRegEx.Replace(strMessage, "$4", newDate) 'where newDate is a string var
But that returns the original message like it was unable to find the 4th group. I am unable to do a string replace with the matched date since there are multiple dates in the string (orderDate, receivedDate, etc) and its possible to match on one of those by accident.
Does anyone know how to replace this text?
Thanks in advance for any help.
There's no apparent reason to use a regex here, use strMessage.Split('|')
.
string str = "blah|blah|blah|blah|blah|blah|blah|blah|blah|oldDate|blah|blah";
string[] tokens = str.Split('|');
tokens[9] = "newDate";
string newStr = String.Join("|", tokens);
If you do need to use a regex, consider using Regex.Replace(string, string)
:
pipeRegEx.Replace(strMessage, "$2" & newDate & "|")
Replace works the other way around - you use groups to keep tokens in your string, not to move them out.
So what you are doing is this, you are calling a Shared
version of the RegEx library on your regex, you aren't actually using your regex to find the match, it is using the "$4"
to find a match, which it isn't. This is why you are getting your original string back.
I would do something like this to get the appropriate group replaced with the new date
Dim matchedGroups As New System.Text.RegularExpressions.Matches = pipeRegEx.Matches(strMessage)
matchedGroups(9) = "new Date"
And then just put your list back together.
You're going about it backward. What you want to do is capture everything preceding the tenth field and then plug it back in along with the new value. You regex looks good, so you just have to change the replacement parameter. Something like this:
newString = pipeRegEx.Replace(strMessage, "$1" + newDate + "|")
(You have to plug the |
back in as well, because the regex consumes it.)
you could use a split
Dim str As String = "blah|blah|blah|blah|blah|blah|blah|blah|blah|oldDate|blah|blah|"
Dim obj As Object = str.Split("|")
obj(9) = "new date"
then
str = strings.join(obj, "|")
or
for each obj1 as object in obj
str&= obj1
next
The Replace method is static
. This means that it's not considering the fact that you called it on theRegEx object pipeRegEx and instead looking for the literal string "$4".
I would rewrite my expression using a zero-width look-behind (?<=expression)
and zero-width look-ahead (?=expression)
so that it only matched the 9th item (and leave it as a string instead of a RegEx). Then you would call:
RegEx.Replace(strMessage,pipeRegEx, newDate);
RegEx syntax resource: http://www.regular-expressions.info/reference.html
Ok, I was able to get the solution with the help of Brad's answer and a different way to get the solution with Kobi's answer, however I felt Brad's was more succinct.
'This regex does a look behind for the string that starts with 9 sections
'and another look ahead for the next pipe. So the result of this regex is only
'the old date value.
Dim pipeRegEx As New RegularExpressions.Regex("(?<=^(([^\|]*\|){9}))([^\|]*)(?=\|)")
'I then store the old date with:
oldDate=pipeRegEx.Match(strMessage).Value
'And replace it with the new date:
strMessage=pipeRegEx.Replace(strMessage, newDate & "|").
精彩评论