Php regex match all but

preg_match_all

Ищет в строке subject все совпадения с шаблоном pattern и помещает результат в массив matches в порядке, определяемом комбинацией флагов flags .

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

Список параметров

Искомый шаблон в виде строки.

Массив совпавших значений, отсортированный в соответствии с параметром flags .

Может быть комбинацией следующих флагов (необходимо понимать, что использование PREG_PATTERN_ORDER одновременно с PREG_SET_ORDER бессмысленно): PREG_PATTERN_ORDER

Упорядочивает результаты так, что элемент $matches[0] содержит массив полных вхождений шаблона, элемент $matches[1] содержит массив вхождений первой подмаски и т.д.

preg_match_all ( «|<[^>]+>(.*)]+>|U» ,
«пример:

это тест

» ,
$out , PREG_PATTERN_ORDER );
echo $out [ 0 ][ 0 ] . «, » . $out [ 0 ][ 1 ] . «\n» ;
echo $out [ 1 ][ 0 ] . «, » . $out [ 1 ][ 1 ] . «\n» ;
?>

Результат выполнения данного примера:

пример: , 
это тест
пример: , это тест

Таким образом, $out[0] содержит массив полных вхождений шаблона, а $out[1] содержит массив подстрок, содержащихся в тегах.

Если шаблон содержит именованные подшаблоны, $matches дополнительно будет содержать записи для ключей с именами этих подшаблонов.

Если шаблон содержит задублированные именованные подшаблоны, то только самый правый подшаблон будет сохранён в $matches[NAME] .

Результат выполнения данного примера:

PREG_SET_ORDER

Упорядочивает результаты так, что элемент $matches[0] содержит первый набор вхождений, элемент $matches[1] содержит второй набор вхождений, и т.д.

preg_match_all ( «|<[^>]+>(.*)]+>|U» ,
«пример:

это тест

» ,
$out , PREG_SET_ORDER );
echo $out [ 0 ][ 0 ] . «, » . $out [ 0 ][ 1 ] . «\n» ;
echo $out [ 1 ][ 0 ] . «, » . $out [ 1 ][ 1 ] . «\n» ;
?>

Результат выполнения данного примера:

пример: , пример: 
это тест
, это тест

PREG_OFFSET_CAPTURE

В случае, если этот флаг указан, для каждой найденной подстроки будет указана её позиция (в байтах) в исходной строке. Необходимо помнить, что этот флаг меняет формат возвращаемого массива matches в массив, каждый элемент которого содержит массив, содержащий в индексе с номером 0 найденную подстроку, а смещение этой подстроки в параметре subject — в индексе 1 .

preg_match_all ( ‘/(foo)(bar)(baz)/’ , ‘foobarbaz’ , $matches , PREG_OFFSET_CAPTURE );
print_r ( $matches );
?>

Результат выполнения данного примера:

Array ( [0] => Array ( [0] => Array ( [0] => foobarbaz [1] => 0 ) ) [1] => Array ( [0] => Array ( [0] => foo [1] => 0 ) ) [2] => Array ( [0] => Array ( [0] => bar [1] => 3 ) ) [3] => Array ( [0] => Array ( [0] => baz [1] => 6 ) ) )

PREG_UNMATCHED_AS_NULL

Читайте также:  Java example code mysql

Если этот флаг передан, несовпадающие подмаски будут представлены значениями null ; в противном случае они отображаются в виде пустых строк ( string ).

В случае если флаги не были указаны, по умолчанию используется PREG_PATTERN_ORDER .

Обычно поиск осуществляется слева направо, с начала строки. Дополнительный параметр offset может быть использован для указания альтернативной начальной позиции для поиска.

Замечание:

Использование параметра offset не эквивалентно замене сопоставляемой строки выражением substr($subject, $offset) при вызове функции preg_match_all() , поскольку шаблон pattern может содержать такие условия как ^, $ или (?<=x). Вы можете найти соответствующие примеры в описании функции preg_match() .

Возвращаемые значения

Возвращает количество найденных вхождений шаблона (которое может быть и нулём) или false в случае возникновения ошибки.

Ошибки

Если переданный шаблон регулярного выражения не компилируется в допустимое регулярное выражение, выдаётся ошибка уровня E_WARNING .

Список изменений

Версия Описание
7.2.0 Теперь константа PREG_UNMATCHED_AS_NULL поддерживается для параметра $flags .

Примеры

Пример #1 Получение всех телефонных номеров из текста.

Пример #2 Жадный поиск совпадений с HTML-тэгами

preg_match_all ( «/(<([\w]+)[^>]*>)(.*?)()/» , $html , $matches , PREG_SET_ORDER );

foreach ( $matches as $val ) echo «совпадение: » . $val [ 0 ] . «\n» ;
echo «часть 1: » . $val [ 1 ] . «\n» ;
echo «часть 2: » . $val [ 2 ] . «\n» ;
echo «часть 3: » . $val [ 3 ] . «\n» ;
echo «часть 4: » . $val [ 4 ] . «\n\n» ;
>
?>

Результат выполнения данного примера:

совпадение: полужирный текст часть 1: часть 2: b часть 3: полужирный текст часть 4: matched: нажми часть 1: часть 2: a часть 3: нажми часть 4: 

Пример #3 Использование именованных подмасок

preg_match_all ( ‘/(?P\w+): (?P\d+)/’ , $str , $matches );

/* Альтернативный вариант */
// preg_match_all(‘/(?\w+): (?\d+)/’, $str, $matches);

Результат выполнения данного примера:

Array ( [0] => Array ( [0] => a: 1 [1] => b: 2 [2] => c: 3 ) [name] => Array ( [0] => a [1] => b [2] => c ) [1] => Array ( [0] => a [1] => b [2] => c ) [digit] => Array ( [0] => 1 [1] => 2 [2] => 3 ) [2] => Array ( [0] => 1 [1] => 2 [2] => 3 ) )

Смотрите также

  • Регулярные выражения PCRE
  • preg_quote() — Экранирует символы в регулярных выражениях
  • preg_match() — Выполняет проверку на соответствие регулярному выражению
  • preg_replace() — Выполняет поиск и замену по регулярному выражению
  • preg_split() — Разбивает строку по регулярному выражению
  • preg_last_error() — Возвращает код ошибки выполнения последнего регулярного выражения PCRE

User Contributed Notes 37 notes

The code that john at mccarthy dot net posted is not necessary. If you want your results grouped by individual match simply use:

Читайте также:  Запуск майнкрафт через python

preg_match_all($pattern, $string, $matches, PREG_SET_ORDER);
?>

preg_match_all(‘/([GH])([12])([!?])/’, ‘G1? H2!’, $matches); // Default PREG_PATTERN_ORDER
// $matches = array(0 => array(0 => ‘G1?’, 1 => ‘H2!’),
// 1 => array(0 => ‘G’, 1 => ‘H’),
// 2 => array(0 => ‘1’, 1 => ‘2’),
// 3 => array(0 => ‘?’, 1 => ‘!’))

preg_match_all(‘/([GH])([12])([!?])/’, ‘G1? H2!’, $matches, PREG_SET_ORDER);
// $matches = array(0 => array(0 => ‘G1?’, 1 => ‘G’, 2 => ‘1’, 3 => ‘?’),
// 1 => array(0 => ‘H2!’, 1 => ‘H’, 2 => ‘2’, 3 => ‘!’))
?>

PREG_OFFSET_CAPTURE always seems to provide byte offsets, rather than character position offsets, even when you are using the unicode /u modifier.

if you want to extract all s from a string:

$pattern = «/<[^>]*>/» ;
$subject = » foo bar» ;
preg_match_all ( $pattern , $subject , $matches );
print_r ( $matches );
?>

output:

Here is a awesome online regex editor https://regex101.com/
which helps you test your regular expressions (prce, js, python) with real-time highlighting of regex match on data input.

Here’s some fleecy code to 1. validate RCF2822 conformity of address lists and 2. to extract the address specification (the part commonly known as ’email’). I wouldn’t suggest using it for input form email checking, but it might be just what you want for other email applications. I know it can be optimized further, but that part I’ll leave up to you nutcrackers. The total length of the resulting Regex is about 30000 bytes. That because it accepts comments. You can remove that by setting $cfws to $fws and it shrinks to about 6000 bytes. Conformity checking is absolutely and strictly referring to RFC2822. Have fun and email me if you have any enhancements!

function mime_extract_rfc2822_address ( $string )
//rfc2822 token setup
$crlf = «(?:\r\n)» ;
$wsp = «[\t ]» ;
$text = «[\\x01-\\x09\\x0B\\x0C\\x0E-\\x7F]» ;
$quoted_pair = «(?:\\\\ $text )» ;
$fws = «(?:(?: $wsp * $crlf )? $wsp +)» ;
$ctext = «[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F» .
«!-‘*-[\\]-\\x7F]» ;
$comment = «(\\((?: $fws ?(?: $ctext | $quoted_pair |(?1)))*» .
» $fws ?\\))» ;
$cfws = «(?:(?: $fws ? $comment )*(?:(?: $fws ? $comment )| $fws ))» ;
//$cfws = $fws; //an alternative to comments
$atext = «[!#-‘*+\\-\\/0-9=?A-Z\\^-~]» ;
$atom = «(?: $cfws ? $atext + $cfws ?)» ;
$dot_atom_text = «(?: $atext +(?:\\. $atext +)*)» ;
$dot_atom = «(?: $cfws ? $dot_atom_text$cfws ?)» ;
$qtext = «[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F!#-[\\]-\\x7F]» ;
$qcontent = «(?: $qtext | $quoted_pair )» ;
$quoted_string = «(?: $cfws ?\»(?: $fws ? $qcontent )* $fws ?\» $cfws ?)» ;
$dtext = «[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F!-Z\\^-\\x7F]» ;
$dcontent = «(?: $dtext | $quoted_pair )» ;
$domain_literal = «(?: $cfws ?\\[(?: $fws ? $dcontent )* $fws ?] $cfws ?)» ;
$domain = «(?: $dot_atom | $domain_literal )» ;
$local_part = «(?: $dot_atom | $quoted_string )» ;
$addr_spec = «( $local_part @ $domain )» ;
$display_name = «(?:(?: $atom | $quoted_string )+)» ;
$angle_addr = «(?: $cfws ? < $addr_spec >$cfws ?)» ;
$name_addr = «(?: $display_name ? $angle_addr )» ;
$mailbox = «(?: $name_addr | $addr_spec )» ;
$mailbox_list = «(?:(?:(?:(? <=:)|,) $mailbox )+)" ;
$group = «(?: $display_name :(?: $mailbox_list | $cfws )?; $cfws ?)» ;
$address = «(?: $mailbox | $group )» ;
$address_list = «(?:(?:^|,) $address )+» ;

Читайте также:  Топ программ на javascript

//output length of string (just so you see how f**king long it is)
echo( strlen ( $address_list ) . » » );

//apply expression
preg_match_all ( «/^ $address_list $/» , $string , $array , PREG_SET_ORDER );

preg_match_all() and other preg_*() functions doesn’t work well with very long strings, at least longer that 1Mb.
In this case case function returns FALSE and $matchers value is unpredictable, may contain some values, may be empty.
In this case workaround is pre-split long string onto parts, for instance explode() long string by some criteria and then apply preg_match_all() on each part.
Typical scenario for this case is log analysis by regular expressions.
Tested on PHP 7.2.0

To count str_length in UTF-8 string i use

$count = preg_match_all(«/[[:print:]\pL]/u», $str, $pockets);

where
[:print:] — printing characters, including space
\pL — UTF-8 Letter
/u — UTF-8 string
other unicode character properties on http://www.pcre.org/pcre.txt

Here is a function that replaces all occurrences of a number in a string by the number—

function decremente_chaine ( $chaine )
//récupérer toutes les occurrences de nombres et leurs indices
preg_match_all ( «/5+/» , $chaine , $out , PREG_OFFSET_CAPTURE );
//parcourir les occurrences
for( $i = 0 ; $i < sizeof ( $out [ 0 ]); $i ++)
$longueurnombre = strlen ((string) $out [ 0 ][ $i ][ 0 ]);
$taillechaine = strlen ( $chaine );
// découper la chaine en 3 morceaux
$debut = substr ( $chaine , 0 , $out [ 0 ][ $i ][ 1 ]);
$milieu = ( $out [ 0 ][ $i ][ 0 ])- 1 ;
$fin = substr ( $chaine , $out [ 0 ][ $i ][ 1 ]+ $longueurnombre , $taillechaine );
// si c’est 10,100,1000 etc. on décale tout de 1 car le résultat comporte un chiffre de moins
if( preg_match ( ‘#[1][0]+$#’ , $out [ 0 ][ $i ][ 0 ]))
for( $j = $i + 1 ; $j < sizeof ( $out [ 0 ]); $j ++)
$out [ 0 ][ $j ][ 1 ] = $out [ 0 ][ $j ][ 1 ] — 1 ;
>
>
$chaine = $debut . $milieu . $fin ;
>
return $chaine ;
>
?>

This is a function to convert byte offsets into (UTF-8) character offsets (this is reagardless of whether you use /u modifier:

$pn_offset = strlen ( mb_substr ( $ps_subject , 0 , $pn_offset , $ps_encoding ));
$ret = preg_match_all ( $ps_pattern , $ps_subject , $pa_matches , $pn_flags , $pn_offset );

Источник

Оцените статью