Мне нужна помощь в изменении регулярного выражения для PHP markdown


Я модифицирую PHP Markdown (PHP-анализатор языка разметки, который используется здесь при переполнении стека), пытаясь реализовать пункты 1, 2 и 3, описанные Джеффом в этом сообщении в блоге . Я легко выполнил последние два, но этот оказался очень сложным:

  1. Удалена поддержка выделения внутри слова , как_это_пример

На самом деле, в "обычной" реализации уценки like_this_example будет отображаться как этот пример. Этот это очень нежелательно; Я хочу, чтобы только _example_ стал примером.

Я заглянул в исходный код и нашел регулярное выражение, используемое для выделения:

var $em_relist = array(
    ''  => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?=\S|$)(?![.,:;]\s)',
    '*' => '(?<=\S|^)(?<!\*)\*(?!\*)',
    '_' => '(?<=\S|^)(?<!_)_(?!_)',
    );
var $strong_relist = array(
    ''   => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?=\S|$)(?![.,:;]\s)',
    '**' => '(?<=\S|^)(?<!\*)\*\*(?!\*)',
    '__' => '(?<=\S|^)(?<!_)__(?!_)',
    );
var $em_strong_relist = array(
    ''    => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?=\S|$)(?![.,:;]\s)',
    '***' => '(?<=\S|^)(?<!\*)\*\*\*(?!\*)',
    '___' => '(?<=\S|^)(?<!_)___(?!_)',
    );

Я попытался открыть его в Приятеле по регулярному выражению, но этого было недостаточно, и, потратив на это полчаса, я все еще не знаю, с чего начать. Есть какие-нибудь предложения?

Некоторые люди, сталкиваясь с проблемой, думают: "Я знаю, я буду использовать регулярные выражения". Теперь у них есть две проблемы.

Author: Andreas Bonini, 2010-08-01

2 answers

Я смог уловить только отдельные _enclosed_ слова с помощью:

$input = 'test of _this_ vs stuff_like_this...and here is _anothermatch_ and_another_fake_string';
$pattern = '#(?<=\s|^)(?<!_)(_[^_]*_)(?!_)#is';
preg_match_all($pattern, $input, $matches);
print_r($matches);

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

$pattern = '#(?<=\s|^)(?<!_)(__[^_]*__)(?!_)#is';
$pattern = '#(?<=\s|^)(?<!_)(___[^_]*___)(?!_)#is';
 2
Author: Jeffrey Blake, 2010-08-01 01:11:55

Я тоже использую RegexBuddy. :)

Возможно, вы захотите попробовать следующий код:

<?php

$line1 = "like_this_example";
$line2 = "I want only _example_ to become example";
$pattern = '/\b_(?P<word>.*?)_\b/si';

if (preg_match($pattern, $line1, $matches))
{
  $result = $matches['word'];
  var_dump($result);
}

if (preg_match($pattern, $line2, $matches))
{
  $result = $matches['word'];
  var_dump($result);
}

?>
 3
Author: Box, 2010-08-01 01:12:36