我正在把我的头撞在桌子上,让我的同事们感到愉快。我目前有以下正则表达式
(^[\w](( \w+)|(\w*))*[\w]$)|(^\w$)
我想要它做的是匹配任何只包含字母数字字符的字符串,没有前导或尾随空格,并且单词之间的空格不超过一个。
在这种情况下,一个词被定义为一个或多个字母数字字符。
这符合我想要的大部分内容,但是从测试开始,它也认为第二个单词的长度必须是2个字符或更长。
试验:
ABC - Pass
Type 1 - Fail
Type A - Fail
Hello A - Fail
Hello Wo - Pass
H A B - Fail
H AB - Pass
AB H - Fail
我出错的任何想法?
答案 0 :(得分:4)
你的正则表达式很接近。您的双字符问题的原因在于:
(^[\w](( \w+)|(\w*))*[\w]$)|(^\w$)
right here ---^
匹配群组( \w+)
后,即一个空格后跟一个或多个\w
,其中第一个词之后的每个词都必须因空格而匹配,那么您将拥有另一个强制性\w
- 这要求字符串中的最后一个单词有两个或更多字符。拿出那个,它应该没问题:
(^[\w](( \w+)|(\w*))*$)|(^\w$)
更简单的版本是:
^\w+( \w+)*$
答案 1 :(得分:2)
首先,我们需要清理你的语料库,因为它们包含破折号。接下来,我们添加一两行肯定会失败,所以我们有一条悲伤的测试路径。这产生了以下语料库:
# /tmp/corpus
ABC
Type 1
Type A
Hello A
Hello Wo
H A B
H AB
AB H
ab $ cd
接下来,我们使用一个锚定的Perl兼容正则表达式和一个仅包含字母数字值的POSIX类。我们使用负前瞻来防止尾随空格,但允许单词之间有一个空格。
$ pcregrep '^([[:alnum:]]+(?!= $) ?)+$' /tmp/corpus
ABC
Type 1
Type A
Hello A
Hello Wo
H A B
H AB
AB H
正如预期的那样,这会产生您期望的8条有效行。成功了!
答案 2 :(得分:0)
\ w会匹配_以及字母数字。因此,如果您不想匹配下划线,则必须使用[a-zA-Z \ d]。
以下表达式应涵盖您的需求:
^ [a-zA-Z \ d] +(?:[A-Za-z \ d] {2,}} * $
或者,如果不支持{min,max}重复,则可以使用以下内容。
^ [A-Za-z \ d] +(?:[A-Za-z \ d] [A-Za-z \ d] +)* $
我们需要{min,max}或双字符组,因为您需要从第二个字开始至少2个字符。
如果允许使用下划线,则以下表达式会更好:
^ \ w +(?:\ w {2,})* $
或没有{min,max}:
^ \ w +(?:\ w \ w +)* $