Building Regex pattern to eventually pick the desired text from the data

Viewed 95

I'm fetching some text-data from a TextArea in my app's UI. The eventual goal is to recognize a pre-determined format/pattern of text form this TextArea's entire data. (I'll be further using such filtered out text, if any, to further process the Employee IDs from such text)

The valid patterns are:

  1. EMP {and any valid ID here}. For e.g. EMP 1234
  2. A URL with this fixed pattern: http://emps/{id} For e.g. http://emps/1234

I'll be searching for such pattern text from the source data.

Here's a bunch of regex pattern and related logic I've developed so far:

string sourceText = "This will contain a bunch of text. Might also contain EMP 1234 and there could be a bunch of text after this pattern. There could again be EMP 4567 or http://emps/2345 We'll be extracting all such patterns. 3 in this case." 
const string regexPattern =
    "(\\bEMP(s|(id)|:|#)?\\s*?(id|#)?\\s*?(:|#)?\\s{1})(?<EMPid>(\\d{1,11}))(\\s*?(,|(and))\\s*?(?<EMPidnew>(\\d{1,11})))*";

var search = new Regex(regexPattern , RegexOptions.IgnoreCase);

MatchCollection matches = searcher.Matches(sourceText );

foreach (Match match in matches)
{
    //If we reach this point it means that the sourceText contained text which matched our pattern
    // From this point I'll be extracting the ID and process it further
}

The REGEX is not case-sensitive, which is intended. The REGEX which I've developed so far, by taking syntax references from some websites, correctly handles my first pattern i.e. of:

  • EMP {and any valid ID here}. For e.g. EMP 1234

But now I'm not sure how I can modify my existing Regex pattern or add upon to the existing to proceed further for my second requirement i.e.
A URL with this fixed pattern:

3 Answers

The valid patterns are:

  1. EMP {and any valid ID here}. For e.g. EMP 1234
  2. A URL with this fixed pattern: http://emps/{id} For e.g. http://emps/1234

Looking at your regex in the code shows you want to go way beyond what you are saying in the quote. For regex I would just use:

(https?://emps/|\bEMP\b\s*)(?<EMPid>\d{1,11})

From what I see a simple match on consecutive digits (two or more) will do the job of \d{2,}.

Using your example, here is what is capture in 3 separate matches (in gold):

Three Matches on \d{2,}

Of course you can improve the logic by knowing that at minimum an employee number has 4 digits so use \d{4,}.

Do they start with a specific number, say 9?, then add that such as 9\d{3,}.


Need the prefix of Emp or whether it is a URL? Then build from this pattern of (EMP\s|/) where we look for emp or a forward slash of a URL. Such as ((EMP\s|/)\d{2,})

enter image description here


The point here is that you can build upon basic principles to find the match. If the whole URL is needed, then add to the building blocks provided above.

You could shorten your pattern a bit and make use of an alternation matching either one of the patterns.

Explanation

  • \b Word boundary
  • (?: Non capture group for the alternation
    • EMP Match literally
    • (?:id|[s:#])? Optionally match either id or one of s : or #
    • \s+ Match 1+ whitespace chars
    • (?<EMPid>\d{1,11}) Named group EMPid, match 1-11 digits
    • | Or
    • (?<EMPurl>https?://emps/\d+) Named group EMPurl Match the url pattern
  • ) Close non capture group
  • (?!\S) Negative lookahead, assert what is on the right is not a non whitespace char (whitespace boundary on the right)

Regex demo | C# demo

Example code

string sourceText = "This will contain a bunch of text. Might also contain EMP 1234 and there could be a bunch of text after this pattern. There could again be EMP 4567 or http://emps/2345 We'll be extracting all such patterns. 3 in this case.";
const string regexPattern = @"\b(?:EMP(?:id|[s:#])?\s+(?<EMPid>\d{1,11})|(?<EMPurl>https?://emps/\d+))(?!\S)";
var search = new Regex(regexPattern , RegexOptions.IgnoreCase);
MatchCollection matches = search.Matches(sourceText);

foreach (Match match in matches)
{
    Console.WriteLine(match.Value.ToString());
}

Output

EMP 1234
EMP 4567
http://emps/2345
Related