我在java中找到了使用正则表达式的一行。它需要用户输入姓氏
return lastName.matches( "[a-zA-z]+([ '-][a-zA-Z]+)*" );
我想知道['-]的功能是什么。另外,为什么我们同时需要一个“+”和一个“*”,而 ['-][a-zA-Z] 在括号中?
你的 RE 是:[a-zA-z]+([ '-][a-zA-Z]+)*
我将把它分解成它的组成部分:
[a-zA-Z]+
字符串必须以任意字母开头,a-z
或者A-Z
,重复一次或多次 ( +
)。
([ '-][a-zA-Z]+)*
[ '-]
<space>
、'
或的任何单个字符-
。
[a-zA-Z]+
同样,任何字母,a-z
或A-Z
,重复一次或多次。
这种字母 ('-
和a-ZA-Z
) 的组合可能会重复零次或多次。
为什么[ '-]
?允许使用连字符的名称,例如Higgs-Boson
或带有撇号的名称,例如O'Reilly
,或带有空格的名称,例如Van Dyke
.
该表达式的[ '-]
意思是“一个'
,,或
-
”。顺序非常重要 - 破折号必须是最后一个,否则字符类将被视为一个范围,并且在空格和引号之间具有代码点的其他字符'
也将被接受。
+
指“一次或多次重复”;*
表示“零次或多次重复”,指的是+
或*
修饰符之前的正则表达式的术语。]
总体而言,该表达式匹配由空格、破折号或单引号分隔的小写和大写字母组。
这意味着它可以是任何字符space
'
或-
(空格,引号破折号)
-
可以这样做,因为\-
它也可以意味着一个范围......比如a-z
这看起来像是一种匹配双管(空格或连字符)或 I-don't-know-what-to-call-it 名称的模式,例如O'Grady
... 例如:
它会匹配
counter-terrorism
De'ville
O'Grady
smith-jones
smith and wesson
但它不会匹配
jones-
O'Learys'
#hashtag
Bob & Sons
这个想法是,在第一个[A-Za-z]+
字母消耗完它可以使用的所有字母之后,匹配将在那里结束,除非下一个字符是空格、撇号或连字符 ( [ '-]
)。如果存在其中一个字符,则必须在其后至少再跟一个字母。
很多人对此有困难。天真地写一些类似的东西[A-Za-z]+[ '-]?[A-Za-z]*
,计算分隔符和额外的字母块是可选的。但它们不是独立可选的;如果有分隔符 ( [ '-]
),则后面必须至少再跟一个字母。否则它会将字符串R'- j'-'
视为有效。你的正则表达式没有这个问题。
顺便说一句,您的正则表达式中有一个错字:[a-zA-z]
. 你要注意这一点,因为[A-z]
它匹配所有的大写和小写字母,所以只要输入有效,它似乎就可以正常工作。但它也匹配几个非字母字符,其代码点恰好位于Z
和之间a
。很少有 IDE 或正则表达式工具会捕捉到该错误。