用空格分割的多个单词的正则表达式

时间:2013-03-04 15:02:47

标签: regex

我正在把我的头撞在桌子上,让我的同事们感到愉快。我目前有以下正则表达式

(^[\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

我出错的任何想法?

3 个答案:

答案 0 :(得分:4)

你的正则表达式很接近。您的双字符问题的原因在于:

(^[\w](( \w+)|(\w*))*[\w]$)|(^\w$)
       right here ---^

匹配群组( \w+)后,即一个空格后跟一个或多个\w,其中第一个词之后的每个词都必须因空格而匹配,那么您将拥有另一个强制性\w - 这要求字符串中的最后一个单词有两个或更多字符。拿出那个,它应该没问题:

(^[\w](( \w+)|(\w*))*$)|(^\w$)

更简单的版本是:

^\w+( \w+)*$

答案 1 :(得分:2)

将PCRE与POSIX Class

一起使用

首先,我们需要清理你的语料库,因为它们包含破折号。接下来,我们添加一两行肯定会失败,所以我们有一条悲伤的测试路径。这产生了以下语料库:

# /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 +)* $