我需要一个相当复杂的正则表达式来完成以下任务:
> replace numbers in a string, i.e. 700, 12.43 by a label (format: {NUMBER:xx})
> ignore: when number is between {braces}, i.e. {7}, {7th}
> ignore: when any character is attached to number, i.e. G3, 7x, 1/2
> except: when
> preceded by $, i.e. $840
> followed by .!?:, i.e. 33! 45.65? 4...
一起采取:
Buy 4 {5} G3 Mac computers for 80% at $600 or 2 for 1/2 price: 200...
dollar. Twice - 2x - as cheap!
期望的输出:
Buy {NUMBER:4} {5} G3 Mac computers for 80% at
$ {NUMBER:600} or {NUMBER:2} for 1/2 price:
{$NUMBER:200} dollar. Twice - 2x - as cheap!
我现在有了这个:
preg_replace("/(?<!{)(?>[0-9]+(?:\.[0-9]+)?)(?!})/", " {NUMBER:$0} ", $string);
输出:
Buy {NUMBER:4} {5} G {NUMBER:3} Mac computers for {NUMBER:80} % at
$ {NUMBER:600} or {NUMBER:2} for {NUMBER:1} / {NUMBER:2} price:
{NUMBER:200} ... dollar. Twice - {NUMBER:2} x - as cheap!
换句话说:忽略异常还没有工作,我不知道如何正确实现它。谁能帮助我?
答案 0 :(得分:2)
这适用于您的测试用例并遵循您的规则,假设大括号正确匹配并且无法使用:
$result = preg_replace(
'/(?<!\{) # Assert no preceding {
(?<![^\s$]) # Assert no preceding non-whitespace except $
\b # Match start of number
(\d+(?:\.\d+)?+) # Match number (optional decimal part)
\b # Match end of number
(?![^{}]*\}) # Assert that next brace is not a closing brace
(?![^\s.!?,]) # Assert no following non-whitespace except .!?,
/x',
'{NUMBER:\1}', $string);
答案 1 :(得分:1)
$string="Buy 4 {5} G3 Mac computers for 80% at \$600 or 2 for 1/2 price: 200... \ndollar. Twice - 2x - as cheap!";
$pattern='/[\s|^|\$]([0-9]+(\.\s+)*)[\s|$|\.|\!|\?|\:|\,]/';
//$count=preg_match_all($pattern, $string, $matches);
//echo "$count\n";
//print_r($matches[1]);
echo preg_replace($pattern,"{NUMBER:\$1}",$string);