Проблема с регулярным выражением для разбора текста (похоже на текстиль)

Я бьюсь головой об стену, пытаясь выяснить (regexp?) Основанное правило синтаксического анализа для следующей проблемы. Я разрабатываю синтаксический анализатор текстовой разметки, похожий на текстильный (использующий PHP), но я не знаю, как получить правильные правила форматирования строки - и я заметил, что обнаруженные текстовые парсеры не могут отформатировать следующий текст как я хотел бы отформатировать:

-*deleted* -- text- and -more deleted text-

Результат, который я хочу получить:

<del><strong>deleted</strong> -- text</del> and <del>more deleted text</del>

То, что я не хочу, это:

<del><strong>deleted</strong> </del>- text- and <del>more deleted text</del>

Любые идеи очень ценятся! Спасибо большое!

ОБНОВИТЬ

я думаю, что я должен был упомянуть, что '-' все еще должен быть допустимым символом (дефис):) - например, следующее должно быть возможным:

-american-football player-

ожидаемый результат:

<del>american-football player</del>

5 ответов

Основано на описании синтаксического анализатора библиотеки RedCloth, с некоторыми изменениями для двойного тире.

@
  (?<!\S)               # Start of string, or after space or newline
  -                     # Opening dash
  (                     # Capture group 1
    (?:                 #   : (see note 1)
      [^-\s]+           #   :
      [-\s]+            #   :
    )*?                 #   :
    [^-\s]+?            #   :
  )                     # End
  -                     # Closing dash
  (?![^\s!"\#$%&',\-./:;=?\\^`|~[\]()<])  # (see note 2)
@x
  • Примечание 1: Это должно соответствовать следующему тире лениво, потребляя при этом любые не одиночные тире и одиночные тире, окруженные пробелом.
  • Примечание 2: Далее следует пробел, пунктуация, разрыв строки или конец строки.

Или уплотнено:

@(?<!\S)-((?:[^-\s]+[-\s]+)*?[^-\s]+?)-(?![^\s!"#$%&',\-./:;=?\\^`|~[\]()<])@

Несколько примеров:

$regex = '@(?<!\S)-((?:[^-\s]+[-\s]+)*?[^-\s]+?)-(?![^\s!"#$%&\',\-./:;=?\\\^`|~[\]()<])@';
$replacement = '<del>\1</del>';

preg_replace($regex, $replacement, '-*deleted* -- text- and -more deleted text-'), "\n";
preg_replace($regex, $replacement, '-*deleted*--text- and -more deleted text-'), "\n";
preg_replace($regex, $replacement, '-american-football player-'), "\n";

Будет выводить:

<del>*deleted* -- text</del> and <del>more deleted text</del>
<del>*deleted*</del>-text- and <del>more deleted text</del>
<del>american-football player</del>

Во втором примере это будет соответствовать просто -*deleted*-, так как нет пробелов перед --, -text- не будет соответствовать, потому что начальный - не предшествует пробел.

strong тег легко

$string = preg_replace('~[*](.+?)[*]~', '<strong>$1</strong>',  $string);

Работаю на других.


Бесстыдный взлом для del тег:

$string = preg_replace('~-(.+?)-~', '<del>$1</del>', $string);
$string = str_replace('<del></del>', '--', $string);

Для одного токена вы можете просто сопоставить:

-((?:[^-]|--)*)-

и заменить на:

<del>$1</del>

и аналогично для \*((?:[^*]|\*{2,})*)\* а также <strong>$1</strong>,

Регулярное выражение довольно просто: буквальный - в обоих концах. В середине, в группе захвата, мы разрешаем все, что не является дефисом или двумя дефисами подряд.

Чтобы также разрешить одиночные тире в словах, как в objective-c, это может работать, принимая тире, окруженные двумя буквенно-цифровыми буквами:

-((?:[^-]|--|\b-\b)*)-

Я думаю, что вы должны сначала прочитать этот предупреждающий знак. Вы не можете разобрать [X]HTML с регулярным выражением

Возможно, вам следует попробовать поискать в Google php html-библиотеке

Вы можете попробовать что-то вроде:

'/-.*?[^-]-\b/'

Где конечный дефис должен находиться на границе слова и предшествовать чему-то, что не является дефисом.

Другие вопросы по тегам