user2530266
user2530266

Reputation: 287

C# regular expression patterns

I have a string like this:

String1=[q:6][ilvl:70](randomword)

and i need three patterns to retrieve the number 70 after the ilvl:, the number 6 after the q: and and one other pattern to retrieve all the ascii characters. I came up with these three patterns but i failed because they dont do excactly the three above.

string rules_1 = @"(?i)\[ilvl:([0-9]{1,2})\]";
string rules_2 = @"(?i)\[q:([0-9]{1,2})\]";
string rules_3 = @"(?i)\(([[:ascii:]+]+)\)";

The first one retrieves [ilvl:70] instead of 70 The second retrieves [q:6] instead of 6 and the third retrieves nothing instead of all ascii characters...

Any regular expression guru that can help me out here?!

Thank you in advance.

Upvotes: 0

Views: 112

Answers (5)

Hogan
Hogan

Reputation: 70538

Non-regex solution:

using System;

public class Program
{
  public static void Main()
  {
    string s1=@"[q:6][ilvl:70](randomword)";

    var tmp = s1.Split(new string [] {":","]" }, StringSplitOptions.None);

    string res1 = tmp[1];
    string res2 = tmp[3];

    string res3 = s1.Split(new string [] {"](",")" }, StringSplitOptions.None)[1];

    Console.WriteLine("1 -> "+res1);
    Console.WriteLine("2 -> "+res2);
    Console.WriteLine("3 -> "+res3);
  }
}

fiddle -> https://dotnetfiddle.net/84myVW

Upvotes: 1

Grant Peters
Grant Peters

Reputation: 7835

Are you actually looking through the 'group' values of the match? The match will return EVERYTHING that matched, not just the things in "()" and group '0' will be everything as well.

This works as expected for me:

string String1="[q:6][ilvl:70](randomword)";

Regex rules_1 = new Regex(@"(?i)\[ilvl:([0-9]{1,2})\]");
Regex rules_2 = new Regex(@"(?i)\[q:([0-9]{1,2})\]");
Regex rules_3 = new Regex(@"(?i)\(([a-zA-Z]+)\)");

var match1 = rules_1.Match(String1);
var match2 = rules_2.Match(String1);
var match3 = rules_3.Match(String1);

var value1 = match1.Groups[1].Value;
var value2 = match2.Groups[1].Value;
var value3 = match3.Groups[1].Value;

Note that i had to change [[:ascii:]+]+ to [a-zA-Z]+ You can't nest the [] selectors (it doesn't make sense for one) and I've never seen :ascii:, but that would match ALL characters in this text anyway ([,:,0,7,etc. are also Ascii characters)

Upvotes: 2

Avinash Raj
Avinash Raj

Reputation: 174826

Your command needs a lookbehind to match all the three cases. You don't need to capture it.

(?:(?<=ilvl:)[^\]]*|(?<=q:)[^\]]*|(?<=\()[^\)]*)

DEMO

The below regex would store the matched characters into groups.

(?:(?<=ilvl:)([^\]]*)|(?<=q:)([^\]]*)|(?<=\()([^\)]*))

DEMO

Explanation:

  • (?:) Means a non capturing group.

  • (?<=ilvl:)[^\]]* matches the characters which are just after to ilvl: until a ] is detected.

  • | logical OR operator.

  • (?<=q:)[^\]] matches the characters which are just after to q: until a ] is detected.

  • | Logical OR operator.

  • (?<=\()[^\)]* matches the characters which are just after to ( until a ) is detected.

Upvotes: 1

Grant Winney
Grant Winney

Reputation: 66489

You could just use string.Split:

var pieces = String1.Split(':', ']', '(', ')');

var qNumber = Convert.ToInt32(pieces[1]);    // 6
var lvlNumber = Convert.ToInt32(pieces[3]);  // 70
var rndWord = pieces[5];                     // randomword

I'm assuming you want any answer that will solve the problem for you.

Regex is powerful, but not always necessary.

Upvotes: 1

zx81
zx81

Reputation: 41848

Retrieve all three with a single regex:

^\[[^:]*:([^\]]*)\]\[[^:]*:([^\]]*)\]\(([^)]*)

In the demo, look at the capture groups in the right pane.

Sample code:

string s1 = @"[q:6][ilvl:70](randomword)";
Match matchResults = null;
var myRegex = new Regex(@"^\[[^:]*:([^\]]*)\]\[[^:]*:([^\]]*)\]\(([^)]*)");
matchResults = myRegex.Match(s1);
string firstNumber = matchResults.Groups[1].Value;
string secondNumber = matchResults.Groups[2].Value;
string yourASCII = matchResults.Groups[3].Value;

Explanation

  • The ^ anchor asserts that we are at the beginning of the string
  • \[[^:]*: matches everything up to the first :
  • ([^\]]*) captures the first value to Group 1
  • \]\[[^:]*: matches everything up to the second :
  • ([^\]]*) captures the second value to Group 2
  • \]\( matches up to the parentheses
  • ([^)]*) captures your characters to Group 3

Upvotes: 2

Related Questions