我想从XML文件中删除所有换行符和回车符,以便所有标记都适合每行。
XML Source示例:
<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>
我的模式出了什么问题?
答案 0 :(得分:3)
你的正则表达式中的第一个[^<>]*
最初吞噬了所有剩余的文本,然后必须回溯一些方式,以便正则表达式的其余部分可以匹配。它只会回溯到文本中的最后换行符。正则表达式的其余部分能够匹配剩下的,所以就是这样。
但是你的正则表达式在任何情况下都只匹配一个换行符,因为它会消耗整个文本。它应该只消耗您要删除的部分。看看这个:
preg_replace('#[\r\n]+(?=[^<>]*</desc>)#', ' ', $data);
找到换行符后,前瞻确认它在<desc>
元素内找到。但是前瞻不会消耗任何东西,所以下一个换行符(如果有的话)仍然可以在下一遍中匹配。
您不能只使用任何结束标记(</\w+>
)进行前瞻匹配,因为这样可以匹配元素之间以及内部的换行符。但是,您可以枚举要处理的元素:
</(?:desc|name|id)>
答案 1 :(得分:2)
除非你想要做的事情比你描述的要多得多,否则我认为你做得太复杂了。你不需要像你一样复杂的正则表达式。尝试使用/\r?\n
。这对我的数据很有用:
$data = preg_replace("/\r?\n/", "", $data);
答案 2 :(得分:1)
我的模式出了什么问题?
这是一种模式,而不是XML解析器。
尝试使用the DOM或其中一个many, many real XML parsers available to PHP。它应该是一个简单的问题,即遍历所有文本节点并trim
使用它们。