Как мне сопоставить одну букву или несколько в регулярном выражении в стиле PHP preg_split - PullRequest
2 голосов
/ 19 сентября 2008

У меня проблема с моим регулярным выражением.

Я хочу захватить <% некоторые вещи%> и мне нужно, что находится внутри <% и%>

Это регулярное выражение работает довольно хорошо для этого.

$matches = preg_split("/<%[\s]*(.*?)[\s]*%>/i",$markup,-1,(PREG_SPLIT_NO_EMPTY  |  PREG_SPLIT_DELIM_CAPTURE));

Я также хочу поймать &amp;% some stuff %&amp;gt;, поэтому мне нужно захватить <% or &amp;lt;% and %> or %&amp;gt; соответственно.

Если я добавлю второй набор символов, это сделает функцию preg_split по-другому (потому что, как вы можете видеть из флага, я пытаюсь поймать, что находится внутри символов.

Желательно, чтобы он совпадал только с &amp;lt; to &amp;gt; and < to >, но в этом нет необходимости

РЕДАКТИРОВАТЬ: ПРЕДМЕТ может содержать несколько совпадений, и мне нужны все из них

Ответы [ 5 ]

9 голосов
/ 19 сентября 2008

В вашем случае лучше использовать preg_match с дополнительным параметром и круглыми скобками:

preg_match("#((?:<|&lt;)%)([\s]*(?:[^ø]*)[\s]*?)(%(?:>|&gt;))#i",$markup, $out);
print_r($out);

Array
(
    [0] => <% your stuff %>
    [1] => <%
    [2] => your stuff
    [3] => %>
)

Кстати, проверьте этот онлайн-инструмент для отладки регулярных выражений PHP, это так полезно!

http://regex.larsolavtorvik.com/

РЕДАКТИРОВАТЬ: Я немного взломал регулярное выражение, так что это быстрее. Протестировал, все работает: -)

Теперь давайте объясним все это:

  • preg_match будет хранить все, что он захватывает, в переменной, переданной как третий параметр (здесь $ out)
  • если preg_match совпадает с чем-либо, оно будет сохранено в $ out [0]
  • все, что внутри (), но не (? :) в шаблоне, будет сохранено в $ out

Паттен в деталях:

#((?:<|&lt;)%)([\s]*(?:[^ø]*)[\s]*?)(%(?:>|&gt;))#i can be viewed as ((?:<|&lt;)%) + ([\s]*(?:[^ø]*)[\s]*?) + (%(?:>|&gt;)).

((?:<|&lt;)%) is capturing < or &lt; then %
(%(?:>|&gt;)) is capturing % then < or &gt; 
([\s]*(?:[^ø]*)[\s]*?) means 0 or more spaces, then 0 or more times anything that is not the ø symbol, the 0 or more spaces.

Почему мы используем [^ ø] вместо. ? Это потому что . очень много времени, механизм регулярных выражений будет проверять все существующие символы. [^ ø] просто проверьте, не является ли символ ø. Никто не использует ø, это международный денежный символ, но если вам интересно, вы можете заменить его на chr (7), который является символом колокольчика, который, очевидно, никогда не будет напечатан на веб-странице.

РЕДАКТИРОВАТЬ2: Я только что прочитал вашу редакцию о захвате всех матчей. В этом случае вы будете использовать preg_match_all таким же образом.

2 голосов
/ 19 сентября 2008
<?php
$code = 'Here is a <% test %> and &lt;% another test %&gt; for you';
preg_match_all('/(<|&lt;)%\s*(.*?)\s*%(>|&gt;)/', $code, $matches);
print_r($matches[2]);
?>

Результат:

Array
(
    [0] => test
    [1] => another test
)
1 голос
/ 19 сентября 2008

Если вы хотите соответствовать, дайте preg_match_all снимок с регулярным выражением , например:

preg_match_all('/((\<\%)(\s)(.*?)(\s)(\%\>))/i', '<% wtf %> <% sadfdsafds %>', $result);

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

Array
(
 [0] => Array
    (
        [0] => <% wtf %>
        [1] => <% sadfdsafds %>
    )

[1] => Array
    (
        [0] => <% wtf %>
        [1] => <% sadfdsafds %>
    )

[2] => Array
    (
        [0] => <%
        [1] => <%
    )

[3] => Array
    (
        [0] =>  
        [1] =>  
    )

[4] => Array
    (
        [0] => wtf
        [1] => sadfdsafds
    )

[5] => Array
    (
        [0] =>  
        [1] =>  
    )

[6] => Array
    (
        [0] => %>
        [1] => %>
    )

)
1 голос
/ 19 сентября 2008

Почему вы используете preg_split, если то, что вы действительно хотите, это то, что соответствует в скобках? Похоже, было бы проще просто использовать preg_match.

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

Согласно PHP документу о синтаксисе регулярных выражений,

Тот факт, что простые скобки выполняют две функции, не всегда полезен. Часто бывают случаи, когда требуется подгруппа группировки без требования захвата. Если после открывающей скобки следует «?:», Подшаблон не выполняет захват и не учитывается при вычислении количества любых последующих поднаборов.

0 голосов
/ 19 сентября 2008

Одно из возможных решений - использовать дополнительные парены, например, так, чтобы исключить их из результатов, так что вы на самом деле только используете 1/2 от общего количества повторений.

это регулярное выражение

$matches = preg_split("/(<|&lt;)%[\s]*(.*?)[\s]*%(>|&gt;)/i",$markup,-1,(PREG_SPLIT_NO_EMPTY  |  PREG_SPLIT_DELIM_CAPTURE));

для ввода

Hi my name is <h1>Issac</h1><% some stuff %>here&lt;% more stuff %&gt; 

вывод будет

Array(
 [0]=>Hi my name is <h1>Issac</h1>
 [1]=><
 [2]=>some stuff
 [3]=>>
 [4]=>here
 [5]=>&;lt;
 [6]=>more stuff
 [7]=>&gt;
)

Что дало бы желаемые результаты, если бы я использовал только четные числа

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...