Php 正则表达式模式内的条件
我想从我的代码中删除任何额外的空白,我正在解析一个docblock。问题是,我不想删除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',
代码中的空白
例如,我使用此选项删除额外的空白:
$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);