简体   繁体   中英

Conditional matching of a string at the end of the line using regex

I need to create a Regex pattern in C# where it is able to take in a string, capture 3 groups, where the final group only captures if the string ends with 'NoClause'. I've provided below a sample input and what I'd like the 3 capture groups to contain.

Sample Input:

Header:Select * From TableName WHERE ColumnName = '53 : ABC' ORDER BY NoClause : NoClause

Desired Output:

Group1: 'Header'
Group2: 'Select * From TableName WHERE ColumnName = '53 : ABC''
Group3: 'NoClause'

The pattern I have so far is:

(\\w+):{1}(.+)\\s*:\\s*(NoClause)

Now for when the string is formatted as the sample input, this does work but the issue I have is when the input string doesn't contain ': NoClause' , in these scenarios that capture group should contain nothing. I've provided examples below of when this doesn't work but needs to.

Header:select * from TableName where ColumnName = '1 ABC'
Header:select * from TableName where ColumnName = '1: ABC'
Header:select * from TableName where ColumnName = '1: ABC' OR ColumnName = '2: DFG' OR ColumnName = '3: HIJ'

When using the above pattern, nothing captures at all. I've attempted to use the '?' as a conditional but am unable to have it match all cases.

I've been fiddling with this all at https://regex101.com/r/wG3aM3/261 .

Things to consider

  1. When using this pattern, only one string of input will be processed at a time, not for example, four separate inputs processed at once
  2. I have the C# code all ready to go, just need the Regex pattern to make it work
  3. The input string will sometimes contain 0 or more semi-colons (:) but it is only after the final semi-colon do I want it to capture the 'NoClause'
  4. This needs to support the edge case, where a ColumnName or value is 'NoClause', very unlikely but needs to support this case regardless.

For interest, the below is my C# code.

Match parameters = Regex.Match(inputString, @"(\w+):{1}(.+)\s*:\s*(NoClause)", RegexOptions.IgnoreCase);

var group1 = parameters.Groups[1].Value;
var group2 = parameters.Groups[2].Value;
bool group3 = parameters.Groups[3].Success;

Have a try with this one:

^(\w+):(.+?)(?:\s*:\s*(NoClause|NoWhereClause))?$

You need to make the last part optional. Also you need to use lazy matching in the middle to avoid capturing the content of the last group into the middle one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM