【问题标题】:Regex to match up to 2 full words and the next word containing the character正则表达式最多匹配 2 个完整单词和包含该字符的下一个单词
【发布时间】:2016-09-27 14:54:57
【问题描述】:

我开发了以下正则表达式以在搜索字段中使用。
目标是使用它来匹配最多 2 个单词,然后是带有字符的完整单词以及之后的所有内容:

/^
    .*?                 # match anything before, as few times as possible
    (
        (?: 
            [^\s]+\s*   # anything followed by whitespace
        ){1,2}          # match once or twice
        \s*?            # match whitespaces that may be left behind, just in case
        [^\s]*?         # match the beginning of the word, if exists
    )?  
    (foo|bar)           # search term(s)
    ([^\s]*\s*.*)       # whatever is after, with whitespace, if it is the end of the word
$/xi

问题在于它并不总是正确匹配。
几个例子,当搜索“a”时:

Fantastic drinks and amazing cakes

Expected match:
$1 = F
$2 = a
$3 = ntastic drinks and amazing cakes

Result:
$1 = Fantastic drinks (space)
$2 = a
$3 = nd amazing cakes

-----------------------------------------

Drinks and party!

Expected match:
$1 = Drinks (space)
$2 = a
$3 = nd party!

Result:
$1 = Drinks and p
$2 = a
$3 = rty!

------------------------------------------

Drinks will be served at the caffetary in 5 minutes

Expected match:
$1 = be served (space)
$2 = a
$3 = t the caffetary in 5 minutes

Result (matches correctly):
$1 = be served (space)
$2 = a
$3 = t the caffetary in 5 minutes

您可以在 https://regex101.com/r/cI7gZ3/1 上进行试验,包括单元测试。

这不起作用的方式很奇怪,超出了我的描述。但是,我的猜测是,这是更喜欢在搜索词之前 有 1-2 个单词的匹配项。

您认为这里可能有什么问题?您认为造成这些问题的原因是什么?

【问题讨论】:

  • Ffffantastic 怎么样?应该如何捕捉零件?
  • 如果第二个捕获组(我称为search term)中的内容是我的示例中使用的“a”,它应该将Ffff 存储在第一个组中,并将ntastic 存储在第三个。
  • 我看到您接受了答案,但有一个问题:您是否只有字母和空格,或者您的输入字符串中也可以包含其他字符?
  • @revo 任何事情都很重要。它不会有换行符,但会有各种空格和符号。主要限于 ISO-8859-15/ANSI/CP-1252/Windows-1252。

标签: php regex pcre


【解决方案1】:

我建议在中使用 \S+{1,2} 的惰性版本

(?: 
    \S+?\s* # anything followed by whitespace
){1,2}?

并删除[^\s]*? # match the beginning of the word, if exists 部分。

updated regex demo

^
  .*? # match anything before, as few times as possible
  (
    (?: 
      \S*?\s* # anything followed by whitespace
    ){1,2}?
    \s* # just in case there's whitespace
  )?
  (a) # search term(s)
  (\S*\s*.*) # whatever is after, without whitespace if it is the end of the word
$

【讨论】:

  • Fantastic drinks and amazing cakes 失败,匹配第一组中的Fant 而不是F
  • 其实我有问题。是不匹配的testing this can be tested。它应该是第一组中的testing this(space),并且与this c 匹配。但它比我想要的要近得多。添加[^\s]*? 回来似乎可以解决它。
  • 好的,这意味着要向问题添加另一个测试用例。我现在在沙坑里,暂时帮不上忙。
  • 别担心。 [^\s]*? 位应该保留。这样,它似乎可以正常工作。我正在使用真实数据和真实搜索对其进行测试,它与我的更改完美配合。我将再次标记为已接受,您可以编辑它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-21
  • 2010-11-15
  • 2012-01-06
相关资源
最近更新 更多