2010-07-27 78 views
3

我想從XML文件中刪除所有換行符和回車符,以便每個標籤都適合一行。正則表達式:從部分字符串中刪除換行符(PHP)

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); 

這種模式校正第二資源,並把它重新站線。但是,它不能糾正第三個資源的兩個換行符,它只能糾正一個。結果是這樣的:

<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> 

我的模式有什麼問題?

回答

3

在你的正則表達式的第一個[^<>]*最初吃掉所有剩餘的文本,然後不得不原路返回一個方式,使正則表達式的其餘部分可以匹配。它只回溯到它的最後,即文本中的換行符。剩下的正則表達式能夠匹配剩下的東西,所以就是這樣。

但是你的正則表達式在任何情況下只會匹配一個換行符,因爲它會佔用整個文本。它應該只消耗你想要刪除的部分。檢查了這一點:換行符發現

preg_replace('#[\r\n]+(?=[^<>]*</desc>)#', ' ', $data); 

後,先行確認發現一個<desc>元素中。但是前瞻並不消耗任何東西,所以下一個換行符(如果有的話)仍然需要匹配。

你不能有先行的比賽剛剛結束的任何標記(</\w+>),因爲這會讓它匹配換行符元素之間以及它們內部。但是,您可以列舉您要處理的元素:

</(?:desc|name|id)> 
2

除非你想要做的比你描述的要多得多,否則我認爲你讓它太複雜了。你不需要像你那樣複雜的正則表達式。嘗試使用/\r?\n。這爲我工作與您的數據:

$data = preg_replace("/\r?\n/", "", $data); 
相關問題