2016-12-27 4 views
1

Итак, я начну с размещением кода:PHP Regex группировки не работает, как ожидалось

$output = preg_replace([ 
    '/#(.*?)/i' 
], [ 
    '<h1>$1</h1>' 
], "#Input"); 

И что в конечном итоге вывод:

<h1></h1> 
Input 

В HTML OPT, выход I» d хотел бы достичь <h1>Input</h1> от ввода #Input, вроде как Markdown, но это для базовой системы редактирования.

Я просмотрел Regex Debugger (here), а трассировка отладки/стека состояла в том, что первая группа была ничем, а индексной группой был #.

Насколько мне известно, единственные вещи, которые были взяты и помещены в группы (мне сказали это), это (...), а от left -> right группы помечены от $1 -> $x.

Извините за чрезмерные вопросы REGEX.

ответ

3

У вас есть дополнительный «?» в вашем Regex.

Попробуйте с:

$output = preg_replace([ 
    '/#(.*)/is' 
], [ 
    '<h1>$1</h1>' 
], "#Input"); 

Поскольку вы не соответствующий какому-либо слова-символы, нечувствительность к регистру не имеет особого смысла, так что вы могли бы написать:

$output = preg_replace([ 
    '/#(.*)/s' 
], [ 
    '<h1>$1</h1>' 
], "#Input"); 

И, конечно же, если бы это было фактическое решение, я бы попытался быть немного более узким в определении моего соответствия (в зависимости от ваших реальных требований). Например .:

$output = preg_replace([ 
    '/#([^#\s]+)/s' 
], [ 
    '<h1>$1</h1>' 
], $string); 

Here у вас есть его работы. И here окончательная версия.

+0

FYI: модификатор 'i' здесь избыточен, а' .' с модификатором '' 'соответствует * любым * символам, которые могут быть проблемой в случае, если текст представляет собой уже отмеченную строку. –

+0

Не так, как я бы построил это регулярное выражение, просто сосредоточившись на непосредственной проблеме, и я предполагаю, что это не полный код вопроса, но ваша точка взята. Я буду работать над улучшением моего ответа для будущих посетителей. Благодарю. – yivi

+0

Да, извиняюсь, поскольку это всего лишь часть моей кодовой базы, которая требовала оператора 'i' столько же, сколько' s', я удалю 's' из моего для будущих посетителей, чтобы не было плохой практики. @ WiktorStribiżew и ответ OP – Jek

1

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

Если вы имеете в виду на самом деле соответствовать что-то, использовать, скажем,

'/#(\S+)/' 

, чтобы соответствовать # и захватить 1 или более не пробельные символы в группу 1.

Вместо \S+, вы можете захотеть использовать более узкий шаблон (например \w+ 1 или более слов, символов [^<]+, чтобы соответствовать 1 или более других, чем < символов или [^\s<]+, чтобы соответствовать 1+, кроме символов пробел и <).

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