Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/294.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,我想从我的代码中删除任何额外的空白,我正在解析一个docblock。问题是,我不想删除代码中的空白 例如,我使用此选项删除额外的空白: $string = preg_replace('/[ ]{2,}/', '', $string); 但我希望将空格保留在 此代码/字符串: This is some text This is also some text <code> User::setup(array( 'key1' => 'value1',

我想从我的代码中删除任何额外的空白,我正在解析一个docblock。问题是,我不想删除
代码中的空白

例如,我使用此选项删除额外的空白:

$string = preg_replace('/[ ]{2,}/', '', $string);
但我希望将空格保留在

此代码/字符串:

This  is some  text
  This is also   some text

<code>
User::setup(array(
    'key1' => 'value1',
    'key2' => 'value1'
));
</code>
应转化为:

This is some text
This is also some text

<code>
User::setup(array(
    'key1' => 'value1',
    'key2' => 'value1'
));
</code>

我该怎么做呢?

用正则表达式解析HTML是个坏主意


使用类似的方法解析HTML并提取部分内容,以替换其中的空格。

您需要的是使用某种形式的HTML解析器对其进行解析

例如,您可以使用DOMDocument遍历所有元素,忽略
code
元素,并从它们的文本节点中去除空白

或者,使用
fopen()
打开文件,这样就有了一个行数组,如果在
code
元素之外,则逐行清除空白

要确定您是否处于
code
元素中,请查找起始标记
,并设置一个标记,表示处于
code
元素模式。然后可以跳过这些行。遇到
时重置标志。您可以通过将嵌套的状态存储为整数来考虑嵌套,即使嵌套的
code
元素不是最明智的想法(为什么要嵌套它们)


当使用PHP和regex解析标记时,
preg\u replace\u callback()
函数与
(?R),(?1),(?2)…
递归表达式结合使用,确实是一个非常强大的工具。以下脚本可以很好地处理测试数据:


您并不是真的在寻找一个条件-您需要一种方法来跳过字符串的某些部分,以便它们不会被替换。使用
preg\u replace
,插入虚拟组并将每个组替换为自身,可以非常轻松地完成此操作。在您的情况下,您只需要一个:

$str = preg_replace("~(<code>.*?</code>)|^ +| +$|( ) +~smi" , "$1$2", $str);
它是如何工作的

  • *?
    -将
    块匹配到第一组中,
    $1
    。这假定格式简单,没有嵌套,但如果需要,可能会很复杂
  • ^+
    -匹配并删除行开头的空格
  • []+$
    -匹配并删除行尾的空格
  • <>代码>()+>代码>匹配行中间的两个或多个空格,并将第一个空格捕获到第二组,<代码> 2美元< /代码>。<李>
替换字符串
$1$2
将保留
块和第一个空格(如果捕获),并删除它匹配的任何其他内容

要记住的事情:

  • 如果未捕获
    $1
    $2
    ,则会将其替换为空字符串
  • 交替(
    a | b | c
    )从左到右工作-当它进行匹配时,它感到满意,不再尝试再次匹配。这就是为什么
    ^++$
    必须在
    ()++
    之前

工作示例:<强> < /强>

,您可能需要考虑为此编写一个简单的解析器。至少您需要区分代码块外部的行和代码块内部的行。你不能用一个regexp来实现这一点;只需编写
/{2,}/
。正则表达式允许条件
(?(x)y | z)
,但我不知道如何将其应用于按行或按块匹配。最好是逐行迭代源文本,设置并反转出现
的状态标志,然后在每一行上应用regex
/^\s{2,}
。@mario我打算把它写下来作为一个答案。。。请这样做,这样我就可以投票了:)@alex:太懒了。你去写,我投票赞成请注意,并非所有出现某种标记的地方(此处:
)都是HTML。。这显然是某种自定义格式标记(如标记或其他),因此完整的HTML/DOM解析器无法工作编辑:事实上这是一个代码文档块..非常有趣。然而,OP并没有提到标签或嵌套标签,我怀疑这使答案比需要的复杂得多。是的,对于非嵌套代码块,这确实是一个非常好的解决方案(而且速度也相当快)+这就是我要找的:)谢谢。
$str = preg_replace("~(<code>.*?</code>)|^ +| +$|( ) +~smi" , "$1$2", $str);