使用OR组时如何找到最短的正则表达式匹配?

时间:2014-08-05 19:58:14

标签: regex

我的意图是将完整的句子(或等效句)与下面的正则表达式相匹配。在第一组中,我希望我的OR模式首先匹配一个句点(表示前一句的结尾),然后,如果128个字符范围内没有句点,则匹配一个引号,然后匹配一个新的line,然后是HTML标记的结尾,然后是单词边界等。

如何设置此正则表达式以优先考虑这样的特定匹配?

<?php
  $regex = '/((\.|"|\n|>|\b).{0,128}\b(manufacturer|manufacture|manufactures)\b.{0,128}(\.|<\/|"|\n|\b))/i';
  $string = '<title>Carter Bearings - Bearings are our Business. Manufacturer of Bearings and Rollers</title>';
  preg_match_all( $regex, $string, $matches );
  var_dump( $matches );
?>

这匹配来自$string的以下字符串:

title>Carter Bearings - Bearings are our Business. Manufacturer of Bearings and Rollers</title

我想匹配大致代表字符串的单独但完整部分的最短版本:

. Manufacturer of Bearings and Rollers</

2 个答案:

答案 0 :(得分:0)

你不能因为一个正则表达式引擎从左到右工作,并且会为你提供从左到右的所有非重叠匹配(带preg_match_all字符串中的可能位置。唯一的方法是找到最短的结果是使用strlen或更好mb_strlen之后。

另外,正如Dalorzo注意到的那样,你的模式可以缩短:

$regex = '/(?:[."\n>]|\b).{0,128}\bmanufacture[rs]?\b.{0,128}(?:[."\n<]|\b)/i';

答案 1 :(得分:0)

我并不是100%确定我理解你需要什么,但我最好猜测字面翻译你说的话:

(\.|
  (?!.{0,128}?\.) # make sure there is no period in the next 128 characters
  (?:"|\n|>|\b)
)
\b(manufacturer|manufacture|manufactures)\b
.{0,128}?         # consume at most 128 characters, but as few as possible
(?=\.|<\/|"|\n)   # ... until you encounter one of these

在这里演示:http://regex101.com/r/iV7xL5/1

这符合您示例中的Manufacturer of Bearings and Rollers