如何使用PHP在标签之间编辑文本

时间:2016-06-15 13:39:05

标签: php regex

我希望捕获数字范围并将其替换为数字,但仅限于特定标记内。

$str = "This is some (the numbers are between 8, 9-12) and we have some 9-12 outside";

输出应为

$str = "This is some (the numbers are between 8, 9, 10, 11, 12) and we have some 9-12 outside";

我只需捕获9-12,它位于括号之间,并且只替换括号外的9-12

2 个答案:

答案 0 :(得分:1)

您可以使用preg_replace_callback和基于\G的模式执行此操作:

$str='This is some (the numbers are between 8, 9-12) and we have some 9-12 outside';

echo preg_replace_callback('~(?:\G(?!\A)|\()[^)0-9]*+(?:[0-9]++(?!-[0-9])[^)0-9]*)*+\K([0-9]++)-([0-9]+)~', function ($m) {
    return implode(', ', range($m[1], $m[2]));
}, $str);

模式细节:

~
(?:  # two possible beginnings
    \G(?!\A)  # position after the previous match
  |           # OR
    \(        # an opening parenthesis
)
[^)0-9]*+ # all that is not a closing parenthesis or a digit 
(?:
    [0-9]++ (?!-[0-9]) # digits not followed by an hyphen and a digit
    [^)0-9]*
)*+
\K  # the match result starts here
([0-9]++) # group 1
-
([0-9]+)  # group 2
~

如果要限制获得匹配的步骤数,可以重写模式的开头:(?:\G(?!\A)|\(),如下所示:\G(?:(?!\A)|[^(]*\()。通过这种方式,模式在开括号之前不会再失败,但会很快达到它,从而避免(限制)模式开始时(大部分时间)失败交替的成本。

答案 1 :(得分:0)

试试这个:

preg_match_all('#\([^\)]+\)#', $str, $matches);
foreach ($matches as $m) {
    $str = str_replace($m, str_replace('-', ', ', $m), $str);
}