How regular expression OR operator is evaluated

家住魔仙堡 提交于 2020-01-11 08:44:15

问题


In T-SQL I have generated UNIQUEIDENTIFIER using NEWID() function. For example:

723952A7-96C6-421F-961F-80E66A4F29D2

Then, all dashes (-) are removed and it looks like this:

723952A796C6421F961F80E66A4F29D2

Now, I need to turn the string above to a valid UNIQUEIDENTIFIER using the following format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and setting the dashes again.

To achieve this, I am using SQL CLR implementation of the C# RegexMatches function with this ^.{8}|.{12}$|.{4} regular expression which gives me this:

SELECT *
FROM [dbo].[RegexMatches] ('723952A796C6421F961F80E66A4F29D2', '^.{8}|.{12}$|.{4}')

Using the above, I can easily build again a correct UNIQUEIDENTIFIER but I am wondering how the OR operator is evaluated in the regular expression. For example, the following will not work:

SELECT *
FROM [dbo].[RegexMatches] ('723952A796C6421F961F80E66A4F29D2', '^.{8}|.{4}|.{12}$')

Is it sure that the first regular expression will first match the start and the end of the string, then the other values and is always returning the matches in this order (I will have issues if for example, 96C6 is matched after 421F).


回答1:


If you are interested in what happens when you use | alternation operator, the answer is easy: the regex engine processes the expression and the input string from left to right.

Taking the pattern you have as an example, ^.{8}|.{12}$|.{4} starts inspecting the input string from the left, and checks for ^.{8} - first 8 characters. Finds them and it is a match. Then, goes on and finds the last 12 characters with .{12}$, and again there is a match. Then, any 4-character strings are matched.

Debuggex Demo

Next, you have ^.{8}|.{4}|.{12}$. The expression is again parsed from left to right, first 8 characters are matched first, but next, only 4-character sequences will be matched, .{12} won't ever fire because there will be .{4} matches!

Debuggex Demo




回答2:


Your Regex ^.{8}|.{12}$|.{4} evaluates to:

Starting with any character except \n { Exactly 8 times }

OR any character except \n { Exactly 12 times }

OR any character except \n { Exactly 4 times } globally

This means that anything after 4 characters in a row will be matched because somewhere in a string of >4 characters there are 4 characters in a row.

1 [false]

12 [false]

123 [false]

1234 [true]

12345 [true]

123456 [true]

1234567 [true]

12345678 [true]

123456789 [true]

1234567890 [true]

12345678901 [true]

123456789012 [true]

You might be looking for:

^.{8}$|^.{12}$|^.{4}$

Which gives you:

1 [false]

12 [false]

123 [false]

1234 [true]

12345 [false]

123456 [false]

1234567 [false]

12345678 [true]

123456789 [false]

1234567890 [false]

12345678901 [false]

123456789012 [true]



来源:https://stackoverflow.com/questions/30531490/how-regular-expression-or-operator-is-evaluated

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!