tags:

views:

968

answers:

3

I'm attempting to find the best methodology for finding a specific pattern and then replace the ending portion of the pattern. Here is a quick example (in C#):

//Find any year value starting with a bracket or underscore

string patternToFind = "[[_]2007";

Regex yearFind = new Regex(patternToFind);

//I want to change any of these values to x2008 where x is the bracket or underscore originally in the text. I was trying to use Regex.Replace(), but cannot figure out if it can be applied.

If all else fails, I can find Matches using the MatchCollection and then switch out the 2007 value with 2008; however, I'm hoping for something more elegant

MatchCollections matches = yearFind.Matches(" 2007 [2007 _2007");
foreach (Match match in matches){
  //use match to find and replace value
}
+3  A: 

You're pattern does not work as described: as described you need to start with "\[|_" (the pipe means OR), and the solution to your actual problem is regex grouping. Surround the part of the pattern you are interested in in brackets "(" and ")" and you can access them in the replacer.

You therefore need a pattern like this: /^(\[|_)2007/

edit: .NET code

string s = Regex.Replace(source, @"^(\[|_)2007", @"$12008");

n.b. misunderstood the requirement, pattern amended

annakata
Grouping is definitely the solution. This will be closer to what was asked for though:string s = Regex.Replace(source, @"([\[_])2007", @"$12008");
Barry Fandango
quite right, misunderstanding - amended
annakata
A: 

To show substitution (using vim in this case). if I have a file with the following contents:

aaa _2007
bbb , 2007
ccc [2007]

and I use the regular expression

:1,$ s/\([_[ ]\)\(2007\)/\12008/g

The first group (in the (, )) will match the character preceding the year and the second group will match the year 2007. The substitution substitutes in the first match and overwrites whatever was matched by the the second group with 2008, giving:

aaa _2008
bbb , 2008
ccc [2008]

Different regex libraries will have minor syntactic variations on this principle.

ConcernedOfTunbridgeWells
+1  A: 

You can wrap the part you want to keep in parentheses to create a sub-match group. Then in the replacement text, use a backreference to put it back in. If I'm understanding what you are trying to do correctly, you would do something like this:

Regex yearFind = new Regex("([[_])2007");
yearFine.Replace("_2007", @"$12008"); // => "_2008"
yearFine.Replace("[2007", @"$12008"); // => "[2008"

The "$1" in the replacement text is replaced with whatever was matched inside the parentheses.

Matthew Crumley