这个正则表达式中单引号的作用是什么?

4

我继承了一些C#代码,其中包含以下正则表达式:

Regex(@"^[a-zA-Z''-'\s]{1,40}$")

除了单引号的作用之外,我理解这个字符串。我搜索了整个网络,但似乎找不到解释。你有什么想法吗?


1
你试过移除它来看哪些内容与表达式匹配,哪些不匹配吗? - Saher Ahwal
你只能留下其中的一个。 - zerkms
4个回答

5
据我所知,这个表达式是多余的。
它匹配 a-zA-Z,或者 ' 字符,或者在 '' 之间的任何字符(当然只有 ' 字符,或者任何空格)。
我使用 RegexPal 进行了测试,似乎除了这些字符以外什么也没有匹配到。也许这个序列是由代码生成的,或者它曾经在早期版本中匹配更广泛的字符范围? 更新: 根据您的评论(匹配名称),我猜测作者认为他通过将连字符放在引号中进行转义,并且不是最出色的软件测试人员。他们可能想表达的是:
Regex(@"^[a-zA-Z'\-\s]{1,40}$") //Escaped the hyphen

这也可以写成:

Regex(@"^[a-zA-Z'\s-]{1,40}$") //Put the hyphen at the end where it's not ambiguous

那么这个不匹配连字符吗?考虑到它的目的(匹配一个名称),我原以为连字符是可以接受的。 - Michael Repucci
只有在连字符被转义(\-)或连字符不会与范围产生歧义(例如在开头或结尾)时,它才会匹配连字符。下面还有一些其他聪明的理论,解释了作者的意思。 - Mike Christensen

1
唯一有意义的使用撇号/单引号三次的方式是第二和第三个实例实际上是花式卷曲的单引号,例如‘、’和‛。如果是这样,更好(更清晰)的表示方法是使用Unicode转义:
Regex(@"^[a-zA-Z'\u2018-\u201B\s]{1,40}$") 

顺便提一下,有些语言(如PowerShell)明确允许使用这些花括号单引号,并将其视为ASCII '(0x27)字符的相同。来自PowerShell 2.0语言规范:

single-quote-character:

' (U+0027) 
Left single quotation mark (U+2018) 
Right single quotation mark (U+2019) 
Single low-9 quotation mark (U+201A) 
Single high-reversed-9 quotation mark (U+201B)

虽然这样做也会匹配花括号之间的字符,但这似乎没有太多意义... - Guffa
@Guffa 如果第一个是 \u2018 而第二个是 \u201B 的话,那确实有意义。请看我的更新答案。 - Joshua Honig
我没有意识到有这么多单引号。它们看起来并没有什么不同。我该如何区分? - Michael Repucci
@jmh_gr:是的,这样做有点意义。你必须查找字符代码才能理解表达式的含义,因此更易维护的方法是将这四个字符单独包含,而不是将其写成一个范围。 - Guffa

1
额外的撇号是多余的,所以它没有太多意义。一个可能性是作者试图转义破折号以将其包含在模式中,但正确的方法是使用反斜杠:
Regex(@"^[a-zA-Z'\-\s]{1,40}$")

在自定义格式字符串中,使用撇号来表示文字是一个例子,作者可能会采用这种方式。


1

由于三个单引号字符是多余的,因此它们代表了单引号字符(#1)以及以单引号开头和结尾的字符范围(#2和#3由连字符分隔)。

看起来这是一个错误,作者似乎本意是在类中包含连字符字符,并通过单引号进行“转义”。如果不进行转义,则连字符表示字符范围,例如a-z和A-Z。

我猜原始作者的意思是[a-zA-Z'\-\s]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接