Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 正则表达式或运算符的求值方式_C#_.net_Sql Server_Regex_Sql Server 2012 - Fatal编程技术网

C# 正则表达式或运算符的求值方式

C# 正则表达式或运算符的求值方式,c#,.net,sql-server,regex,sql-server-2012,C#,.net,Sql Server,Regex,Sql Server 2012,在T-SQL中,我使用函数生成了。例如: 723952A7-96C6-421F-961F-80E66A4F29D2 然后,删除所有破折号(-),如下所示: 723952A796C6421F961F80E66A4F29D2 现在,我需要使用以下格式将上面的字符串转换为有效的UNIQUEIDENTIFIER,并再次设置破折号 为了实现这一点,我正在使用sqlclr实现C#RegexMatches函数与这个^.{8}.{12}$|.{4}正则表达式相匹配,它给出了以下结果: SELECT * FR

T-SQL中,我使用函数生成了。例如:

723952A7-96C6-421F-961F-80E66A4F29D2
然后,删除所有破折号(
-
),如下所示:

723952A796C6421F961F80E66A4F29D2
现在,我需要使用以下格式将上面的字符串转换为有效的
UNIQUEIDENTIFIER
,并再次设置破折号

为了实现这一点,我正在使用
sqlclr
实现
C#
RegexMatches
函数与这个
^.{8}.{12}$|.{4}
正则表达式相匹配,它给出了以下结果:

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

使用上述方法,我可以很容易地再次构建正确的
UNIQUEIDENTIFIER
,但我想知道在正则表达式中如何计算
运算符。例如,以下操作将不起作用:

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


是否确定第一个正则表达式将首先匹配字符串的开头和结尾,然后匹配其他值,并始终按此顺序返回匹配项(例如,如果
96C6
421F
之后匹配,我将遇到问题)。

您的正则表达式
^.{8}.{12}$.{4}
的计算结果为:

以除\n{正好8次}以外的任何字符开头

或除\n{正好12次}以外的任何字符

或全局\n{正好4次}以外的任何字符

这意味着一行中4个字符之后的任何内容都将被匹配,因为在大于4个字符的字符串中,一行中有4个字符

1[假]

12[假]

123[假]

1234[正确]

12345[正确]

123456[正确]

1234567[正确]

12345678[正确]

123456789[正确]

1234567890[正确]

12345678901[正确]

123456789012[正确]

您可能正在寻找:

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

这给了你:

1[假]

12[假]

123[假]

1234[正确]

12345[假]

123456[假]

1234567[假]

12345678[正确]

123456789[假]

1234567890[假]

12345678901[假]


123456789012[true]如果您对使用时发生的情况感兴趣,答案很简单:正则表达式引擎从左到右处理表达式和输入字符串

以您拥有的模式为例,
^.{8}|.{12}$|.{4}
从左侧开始检查输入字符串,并检查
^.{8}
-前8个字符。找到他们,这是一个匹配。然后,继续查找带有
{12}$
的最后12个字符,并且再次存在匹配项。然后,匹配任何4个字符的字符串

接下来是
^.{8}|.{4}|.{12}$
。再次从左到右解析表达式,首先匹配前8个字符,但是接下来,将只匹配4个字符的序列,
{12}
将永远不会触发,因为将有
{4}
匹配


另外,之所以
^.{8}|.{4}|.{12}$
返回四个而不是最后一个12个的块,是因为使用了匹配的第一个
或(|)
值,而不是最合格的值。正则表达式解析器在看到
{12}$
之前先看到
{4}
,因此在四元组中匹配它们。@EBrown,这种情况是复杂应用程序的一部分。我无法改变做事的方式。只需要找到一种方法来处理这种情况。@EBrown,所以它总是按顺序匹配
块?为什么要使用正则表达式来分离它?您确切地知道破折号应该重新插入的位置。例如,
STUFF(STUFF(STUFF(UnDashedValue,21,0',-',17,0',-',13,0',-',9,0',-)
完成了这项工作。我们必须使用不同的clear定义。也就是说,在我看来,你不得不问一个关于regex变量的问题,这可能并不“清楚”。