正则表达式双白空间分离问题

时间:2010-08-10 13:59:13

标签: regex

我希望正则表达式匹配由双倍或更多空格字符分隔的单词,例如

ABC  DE  FGHIJ   KLM    NO  P  QRST

注意字母表之间有两个或更多的空格。为这样的问题编写正则表达式很容易,因为我只需要前4个单词,因为我们可以使用\S+\S+?来搜索单词

但是,对于我的问题,一个单词中只能出现1个空格,例如

AB C  DE  FG HIJ   KLM    NO  P  QRST

这里AB C是一个单词,FG HIJ也是一个单词。简而言之,我们想要隔离由双或更多空格组成的字符,我尝试使用这个正则表达式,

.+?  +.+?  +.+?  +.+?  +

它非常迅速地匹配,但它不匹配的字符串需要太多时间。 (这里以4个匹配为例,实际上我需要匹配更多)。

我需要一个更好的正则表达式才能实现这一点,因此可以避免所有的回溯。 [^ ]*是一个正则表达式,它将匹配最后遇到的空格。我们不能指定一个否定的字符集,我们在单个空格的情况下继续匹配,遇到2时断开吗?我尝试过使用积极的前瞻但却失败了。

我真的很感谢你的帮助。提前谢谢。

Saad的

6 个答案:

答案 0 :(得分:3)

最简单的解决方案是在\s{2,}上拆分以获得您想要的“字词”,但如果您坚持扫描令牌,那么就像以前一样\S+,您现在拥有的是什么是\S+(\s\S+)*。这正是它所说的:\S+,后跟零或更多(\s\S+)。您可以使用非捕获组来提高性能,即\S+(?:\s\S+)*。如果你的味道支持它以获得额外的提升,你甚至可以使每次重复占有欲,即\S++(?:\s\S++)*+

这是一个Java代码片段,用于演示:

    String text = "AB C  DE  FG HIJ   KLM    NO  P  QRST";
    Matcher m = Pattern.compile("\\S++(?:\\s\\S++)*+").matcher(text);
    while (m.find()) {
        System.out.println("[" + m.group() + "]");
    }

打印:

[AB C]
[DE]
[FG HIJ]
[KLM]
[NO]
[P]
[QRST]

如果这是您的要求,您当然可以替换空格字符而不是\s

参考

答案 1 :(得分:1)

如果你知道分隔符是什么(\ s \ s +),你可以分割而不是匹配。 简单地分成两个或多个空格。

此致

RBO

答案 2 :(得分:1)

使用这种模式怎么样:

\s{2,}

答案 3 :(得分:1)

我认为匹配2个或更多空格会更简单:

  

\ S {2,}

在PHP中,拆分看起来像这样

  

$ list = preg_split('/ \ s {2,} /',$ string);

答案 4 :(得分:0)

为什么不能像\ s \ s +(一个空白字符,然后是一个或多个空白字符)?

编辑:对我来说,无论你使用什么语言/工具包,都可能不支持直接使用正则表达式“拆分”字符串。在这种情况下,您可能希望实现该功能,而不是尝试匹配输入中的 WORDS ,而不是匹配 SPACES ,并使用这些匹配中的信息(位置,长度)来提取匹配之间的单词。在某些语言(.NET,其他语言)中,此功能是内置的。

答案 5 :(得分:0)

如果你想匹配所有单词(允许一行中有一个空格),请尝试\S+(?:[ ]\S+)*(字符类不是必需的,可以只是一个空格字符,但为了清楚起见,我将其包括在内)。它指定至少需要一个非空白字符,并且一个空格不能跟随另一个空格。

你没有提到你正在使用的语言,但这是PHP中的一个例子:

$string = "AB C  DE  FG HIJ   KLM    NO  P  QRST";
$matches = array();
preg_match_all('/\S+(?:[ ]\S+)*/', $string, $matches);
// $matches will contain 'AB C', 'DE', 'FG HIJ', 'KLM', 'NO', 'P', 'QRST'

如果要求每个字最多只有一个空格,只需将最后的*更改为?\S+(?:[ ]\S+)?