正则表达式:从部分字符串中删除换行符(PHP)
Posted
技术标签:
【中文标题】正则表达式:从部分字符串中删除换行符(PHP)【英文标题】:Regex: remove line breaks from parts of string (PHP) 【发布时间】:2011-03-21 09:48:47 【问题描述】:我想从 XML 文件中删除所有换行符和回车符,以便所有标签各占一行。
XML 源示例:
<resources>
<resource>
<id>001</id>
<name>Resource name 1</name>
<desc>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas nibh magna, fermentum et pretium vel, malesuada sit amet dolor. Morbi dictum, nunc sed interdum facilisis, ligula enim pharetra tortor, at egestas urna massa non nulla.</desc>
</resource>
<resource>
<id>002</id>
<name>Resource name 2</name>
<desc>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas nibh magna, fermentum et pretium vel, malesuada sit amet dolor. Morbi dictum, nunc sed interdum facilisis, ligula enim pharetra tortor, at egestas urna massa non nulla.
</desc>
</resource>
<resource>
<id>003</id>
<name>Resource name 3</name>
<desc>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas nibh magna, fermentum et pretium vel, malesuada sit amet dolor.
Morbi dictum, nunc sed interdum facilisis, ligula enim pharetra tortor, at egestas urna massa non nulla.
</desc>
</resource>
</resources>
我的看法:
$pattern = "#(\t\t<[^>]*>[^<>]*)[\r\n]+([^<>]*</.*>)#";
$replacement = "$1$2";
$data = preg_replace($pattern, $replacement, $data);
此模式更正第二个资源并将其放回原来的位置。但是,它不会更正来自第 3 个资源的 2 个换行符,它只会更正一个。结果是这样的:
<resources>
<resource>
<id>001</id>
<name>Resource name 1</name>
<desc>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas nibh magna, fermentum et pretium vel, malesuada sit amet dolor. Morbi dictum, nunc sed interdum facilisis, ligula enim pharetra tortor, at egestas urna massa non nulla.</desc>
</resource>
<resource>
<id>002</id>
<name>Resource name 2</name>
<desc>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas nibh magna, fermentum et pretium vel, malesuada sit amet dolor. Morbi dictum, nunc sed interdum facilisis, ligula enim pharetra tortor, at egestas urna massa non nulla.</desc>
</resource>
<resource>
<id>003</id>
<name>Resource name 3</name>
<desc>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas nibh magna, fermentum et pretium vel, malesuada sit amet dolor.
Morbi dictum, nunc sed interdum facilisis, ligula enim pharetra tortor, at egestas urna massa non nulla.</desc>
</resource>
</resources>
我的模式有什么问题?
【问题讨论】:
【参考方案1】:你的正则表达式中的第一个[^<>]*
最初会吞噬所有剩余的文本,然后必须回溯一个方法,以便正则表达式的其余部分可以匹配。它只回溯到它必须的地方,即到文本中的 last 换行符。正则表达式的其余部分能够匹配剩下的内容,就是这样。
但是您的正则表达式在任何情况下都只会匹配一个换行符,因为它会占用整个文本。它应该只消耗您要删除的部分。看看这个:
preg_replace('#[\r\n]+(?=[^<>]*</desc>)#', ' ', $data);
找到换行符后,先行确认它是在<desc>
元素中找到的。但是前瞻不会消耗任何东西,因此下一个换行符(如果有的话)仍然存在,以便在下一次传递时匹配。
您不能让前瞻匹配任何结束标记 (</\w+>
),因为这会使其匹配 元素之间以及元素内部的换行符。但是,您可以列举要处理的元素:
</(?:desc|name|id)>
【讨论】:
【参考方案2】:除非你想要做的事情比你描述的要多得多,否则我认为你把它弄得太复杂了。您不需要像您所拥有的那样复杂的正则表达式。尝试使用/\r?\n
。这对我有用你的数据:
$data = preg_replace("/\r?\n/", "", $data);
【讨论】:
【参考方案3】:我的模式有什么问题?
这是一种模式,而不是 XML 解析器。
尝试使用the DOM,或many, many real XML parsers available to php 之一。遍历所有文本节点并trim
ming 它们应该很简单。
【讨论】:
以上是关于正则表达式:从部分字符串中删除换行符(PHP)的主要内容,如果未能解决你的问题,请参考以下文章