Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用PHP编辑标记之间的文本_Php_Regex - Fatal编程技术网

如何使用PHP编辑标记之间的文本

如何使用PHP编辑标记之间的文本,php,regex,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。您可以使

我想捕获数字范围并用数字替换它,但只在特定标记内

$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

您可以使用
preg\u replace\u 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)\[^(]*\()
。这样,模式在打开括号之前不会再失败,但会很快达到它,从而避免(限制)a的成本(大部分时间)模式开始时交替失败。

尝试以下操作:

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

仅使用正则表达式无法执行此操作。您可以创建一个函数来提取区间值,将其转换为一个数字列表,然后替换区间。@JorgeCampos我处理了第一部分,但如何将替换仅限于括号内的子字符串?
\(*([\d]+-[\d]+)\)
你只得到了第一组:这真是不可思议!我无法相信它的无能为力。我怀疑是否有更好的答案!@All:谢谢,但模式通常可以改进(特别是当你有关于字符串的其他信息时)。为了更好地理解发生了什么,需要花时间来了解
\G
模式是如何设计的(SO中有许多示例),它们是如何工作的以及为什么工作的(是连续的还是不连续的)。一旦完成,第二次,您可以搜索所有格量词,这些量词仅用于改进模式。