更新:实际上php不支持可变长度的lookbehind。这种方法在php中是不可能的。任何可变长度的lookbehind都会出现错误“Compilation failed:lookbehind assertion is not fixed length”
我有以下正则表达式(我正在使用php):
/\d{2}\s\b(ans|year|years|sana|años|anos|sna)\b/i
匹配以下模式:
22 years
49 ans
98 anos
如果输入前面有某些单词(“since”,“depuis”等),我需要使它不匹配
所以:
I'm 22 years
I have 49 years
会匹配,而:
Since 19 years
Depuis 10 ans
不匹配。
我试过这个,没有效果:
/(?<!(depuis|since|monz))\d{2}\s\b(ans|year|years|sana|años|anos|sna)\b/i
提前致谢。
答案 0 :(得分:1)
你的外观形象不佳。 lookbehinds中的“或”条件(在PHP中用于parens时)需要相同的长度。否则你可以像
一样逐个编写整个lookbehind条件$str = "I'm 22 years and I have 49 years but Since 19 years and Depuis 10 ans";
preg_match_all(
'~
(?<!
\bdepuis\s |
\bsince\s |
\bmonz\s
)
\d{2}\s
(?:
ans? |
years? |
sana |
años? |
anos? |
sna
)\b
~xi',$str,$m);
print_r($m);
最后一个单词和所需部分之间可能存在多个空格(如下面评论中的@nhahtdh)。虽然这不是一个单一的模式,但你可以避免这种情况。
$pat =
'~
(
(?(?<=^)(?=\s*) # if it is the beginning of the string
(?:\s*) # match possible spaces
| # otherwise match
(?:
(?<=\s) # following a space,
(?: # a word that is not listed below
(?!(?:
depuis |
since |
monz
))
\S
)+
\s+ # and 1 or more spaces
)
)
)
\d{2}\s+ # then your pattern itself
(?:
ans? |
years? |
sana |
años? |
anos? |
sna
)\b
~xi';
preg_match_all($pat,$str,$matches);
foreach ($matches[0] as $k => &$v)
// replace the previous word if any
$v = substr($v,strlen($matches[1][$k]));
// and delete the reference
unset($v);
print_r($matches);