Проблема с регулярным выражением для разбора текста (похоже на текстиль) - PullRequest
2 голосов
/ 14 июля 2010

Я бьюсь головой об стену, пытаясь выяснить (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>

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

UPDATE

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

-american-football player-

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

<del>american-football player</del>

Ответы [ 5 ]

2 голосов
/ 14 июля 2010

На основе описания библиотеки *1003* библиотеки 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- не будет сопоставлено, потому что начальному - не предшествует пробел.

1 голос
/ 14 июля 2010

Тег strong прост:

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

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


Бесстыдный хак для тега del:

$string = preg_replace('~-(.+?)-~', '<del>$1</del>', $string);
$string = str_replace('<del></del>', '--', $string);
1 голос
/ 14 июля 2010

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

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

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

<del>$1</del>

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

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

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

-((?:[^-]|--|\b-\b)*)-
0 голосов
/ 14 июля 2010

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

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

0 голосов
/ 14 июля 2010

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

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

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

...