2012-02-03 3 views
4

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

Я работаю в PHP.

В чем-то вроде:

preg_replace('/(?:\n|^)(={3,6})([^=]+)(\1)/','<h#>$2</h#>', $input); 

Есть ли способ, чтобы выяснить, сколько «=» (={3,6}) совпадают, так что я могу это обратная ссылка, где «#» s есть?

Эффективно превращая:

===Heading 3=== into <h3>Heading 3</h3> 
====Heading 4==== into <h4>Heading 4</h4> 
... 

ответ

0

Я хотел бы сделать это следующим образом:

<?php 
$input = '===Heading 3==='; 
$h_tag = preg_replace_callback('#(?:\n|^)(={3,6})([^=]+)(\1)#', 'paragraph_replace', $input); 
var_dump($h_tag); 

function paragraph_replace($matches) { 
    $length = strlen($matches[1]); 
    return "<h{$length}>". $matches[2] . "</h{$length}>"; 
} 
?> 

Выход:

string(18) "<h3>Heading 3</h3>" 
2

Нет, PCRE не может сделать это. Вместо этого вы должны использовать preg_replace_callback и сделать некоторый характер подсчета, то:

preg_replace_callback('/(?:\n|^)(={3,6})([^=]+)(\1)/', 'cb_headline', $input); 

    function cb_headline($m) { 
     list(, $markup, $text) = $m; 

     $n = strlen($markup); 
     return "<h$n>$text</h$n>"; 
    } 

Кроме того, вы можете быть снисходительными с задними === знаками. Не используйте обратную ссылку, но допускайте переменное число.

Вы также, возможно, пожелает использовать /m флаг для регулярных выражений, так что вы можете держать ^ вместо более сложного (?:\n|^) утверждения.

+1

+1, и пока вы на нем, замените '(?: \ N | ^)' на '(? M) ^' (т. Е. Включите многострочный режим, поэтому '^' становится * line * anchor вместо * start-of-string). –

2

Это очень просто с модификатором e в регулярном выражении, нет необходимости в preg_replace_callback

$str = '===Heading 3==='; 
echo preg_replace('/(?:\n|^)(={3,6})([^=]+)(\1)/e', 
    'implode("", array("<h", strlen("$1"), ">$2</h", strlen("$1"), ">"));', 
$str); 

или таким образом

echo preg_replace('/(?:\n|^)(={3,6})([^=]+)(\1)/e', 
    '"<h".strlen("$1").">$2</h".strlen("$1").">"', 
$str); 
3

Вы можете использовать:

preg_replace('/(?:\n|^)(={3,6})([^=]+)(\1)/e', 
      "'<h'.strlen('$1').'>'.'$2'.'</h'.strlen('$1').'>'", $input); 

Ideone Link

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