2016-09-06 6 views
1

Для очистки данных мне нужно перенести пунктуацию (запятые и периоды), которые происходят непосредственно перед некоторыми закрывающими тегами (a, b, i, strong, em) с другой стороны этих закрывающих тегов.RegEx для перемещения пунктуации вне метки?

Например, этот бит текста:

<p>Lorem ipsum dolor sit <i>amet,</i> consectetur adipiscing elit.</p> 

должны быть преобразованы в это:

<p>Lorem ipsum dolor sit <i>amet</i>, consectetur adipiscing elit.</p> 

Если возможно, было бы здорово, если регулярное выражение может также перемещать пробелы, которые происходят на конец тегов, хотя я предполагаю, что это может быть достигнуто простым запуском preg_replace дважды, один раз для пробелов и снова для пунктуации. Например:

<p>Lorem ipsum dolor sit <i>amet, </i>consectetur adipiscing elit.</p> 
<p>Lorem ipsum dolor sit <i>amet</i>, consectetur adipiscing elit.</p> 
+0

Просить нас написать это для вас не так, как пользоваться этим сайтом. Удачи и боги! Я рекомендую вам начать с написания регулярного выражения, которое помещает символы, которые вы хотите переместить в группе захвата, а затем перемещает их на другую сторону в заменяющей строке. – 4castle

+0

следует ли рассматривать такой случай ' amet, go,'? – RomanPerekhrest

+0

@RomanPrekhrest: Хорошая точка. Я думаю, что нет - этот вопрос в первую очередь касается чистки пунктуации рядом с закрывающим тегом, поэтому выясняя, следует ли следовать за пунктуацией внутри тега пробелом или выяснить, следует ли перемещать пробел после открытия тега на другую сторону этот открытый тег, кажется, выходит за пределы текущей области. –

ответ

2

Этот метод использует две группы захвата: один захватывает запятую или период, за которым следуют ноль или больше пробелов, а второй фиксирует закрывающий тег. preg_replace используется для изменения их порядка.

$string = '<p>Lorem ipsum dolor sit <i>amet, </i>consectetur adipiscing elit.</p>'; 
$pattern = '/([,.] *)(<\/(?:a|b|em|i|strong)>)/g'; 
$replacement = '$2$1'; 

$result = preg_replace($pattern, $replacement, $string); 

Адрес online demo.

+0

Исправлено. Не стесняйтесь редактировать ответ, если он неудовлетворительный. Спасибо за подсказку re: '\ 0', это аккуратно! –

+1

Хорошо выглядит сейчас :) Всегда лучше использовать группу без захвата, если это возможно, потому что она выполняется быстрее и не возится с группами захвата в матче. – 4castle

1

Игнорируя все вопросы о the horrors awaiting the regex parsing of HTML, это работает для меня:

$re = "/([\\W]+)(<\\/(a|b|em|i|strong)>)/"; 
$str = "<p>Lorem ipsum dolor sit <i>amet, </i>consectetur adipiscing elit.</p>"; 
$subst = "$2$1"; 

$result = preg_replace($re, $subst, $str); 

Вы можете проверить это online here.

+2

Не нужно удваивать все: '([\ W] +) (\ <\/\ b (a | b | em | i | strong) \ b \>'. Кроме того, если вы используете другой разделитель (например, ' ~ '), ваше регулярное выражение становится еще яснее: [**' ~ (\ W +) () ~ '**] (https: // regex101 .com/r/hR2wY6/2) – Jan

+0

'\ b' не требуется, потому что у вас есть символьные литералы с обеих сторон этих слов, которые не являются словами. – 4castle

+0

Двойные escape-последовательности происходят из генератора кода regex101. Однако вы избавились от '\ b' s и еще нескольких ненужных escape-символов. –

 Смежные вопросы

  • Нет связанных вопросов^_^