Migwell
Migwell

Reputation: 20169

Regex that matches everything before an underscore

I have a fair bit of RegEx knowledge, but I'm stumped by this one. I need a RegEx that matches everything before the last underscore, but only if the text after the underscore is "self", "ally" or "enemy".

So if I have input strings like this:

"hero_anti_infantry_melee_2_self"
"anti_infantry_ranged_2_ally"
"suppression_aoe_enemy"
"reinforce_btn_down"
"inset_energy"
"suppressed"

I want them to output as:

"hero_anti_infantry_melee_2"
"anti_infantry_ranged_2"
"suppression_aoe"
//No Match (not match because it isn't enemy, ally, or self after the underscore)
//No Match
//No Match (not underscores or enemy/ally/self

This is using the C# RegEx engine, and it can use any RegEx options necessary.

Upvotes: 1

Views: 3010

Answers (5)

josephj1989
josephj1989

Reputation: 9709

This works

static void Main(string[] args)
        {
            string [] vars=
       new string[]{ @"data\ui\textures\generic\decorators\hero_anti_infantry_melee_2_self",
@"data\ui\textures\generic\decorators\anti_infantry_ranged_2_ally",
@"data\ui\textures\generic\decorators\suppression_aoe_enemy",
@"data\ui\textures\generic\decorators\reinforce_btn_down",
@"data\ui\textures\generic\decorators\rinset_energy",
@"data\ui\textures\generic\decorators\suppressed" };

 Regex re = new Regex("^(.*)_(ally|self|enemy)");

var xx= vars.Select(x => re.Match(x).Groups[1]);
foreach (var y in xx)
    Console.WriteLine(y.Value.ToString());
        }
    }

Upvotes: 0

configurator
configurator

Reputation: 41690

What you want is a lookahead. Something like this should work:

new Regex(@"^.*(?=_(ally|self|enemy)$)")

The (?=...) means pretty much what you wanted:

Zero-width positive lookahead. Matches at a position where the pattern inside the lookahead can be matched. Matches only the position. It does not consume any characters or expand the match. In a pattern like one(?=two)three, both two and three have to match at the position where the match of one ends.

edit: MSDN has better examples for this.

Upvotes: 5

sjngm
sjngm

Reputation: 12871

I can't yet comment to the other answer by Macy Abbey, so here it goes:

If you only want to match the word at the end you need to append a "$" at the end of the search string:

/(.+)_(ally|self|enemy)$/

Upvotes: 0

dhinesh
dhinesh

Reputation: 4764

This method will give you the desired result. This uses named group regex match.

 private static string GetStringBeforeUnderscore(string input)
 {
     string matchedValue = 
         Regex.Match(input, "(?<Group>.*)[_](self|ally|enemy)").Groups["Group"].ToString();

     return matchedValue;
 }

Upvotes: 1

Macy Abbey
Macy Abbey

Reputation: 3887

/(.+)_(ally|self|enemy)/

Upvotes: 0

Related Questions