2010-07-27 6 views
3

Я хочу удалить все разрывы строк и возврат каретки из файла XML, чтобы все теги соответствовали одной строке. Пример ИсточникRegex: удалить разрывы строк из частей строки (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); 

Эта модель корректирует 2-й ресурс и помещает его на своей линии. Однако он не исправляет 2 разрыва строки с 3-го ресурса, он только корректирует его. В результате получилось следующее:

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

Что не так с моим рисунком?

Это шаблон, а не XML-парсер.

Попробуйте использовать the DOM или один из many, many real XML parsers available to PHP. Это должен быть простой вопрос, проходящий через все текстовые узлы и trim ming them.

2

Если вы не хотите, чтобы вы делали гораздо больше, чем описываете, я думаю, вы делаете это слишком сложно. Вы не нуждаетесь в таком сложном регулярном выражении, как у вас. Попробуйте использовать только /\r?\n. Это работает для меня с вашими данными:

$data = preg_replace("/\r?\n/", "", $data); 
Смежные вопросы