Using regular expression subpattern to instead of using regular expression 2 times in php

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-16 19:17:08

问题


I'm interested if its possible to make include subpattern (child pattern) into a another pattern that would allow me to convert those 2 preg_match and preg_match_all into one preg_match/preg_match_all.

<?php

$data = 'office phones tel1 6665555998 tel2 555666888 tel3 555688855 home phones tel1 555222555 tel2 555222444 tel3 555666888';

preg_match('/phones(.*)home phones/', $data, $matches); // 1st operation
preg_match_all('/[0-9]{4,12}/',  $matches[1],  $matches); // 2nd operation

var_dump($matches);

// Question is: How to get same output with just only one preg_match

preg_match('/phones(SUBPATTERN)home phones/', $data, $result_data);

// Where SUBPATTERN is a pattern that would do exactly what 2nd operation did
// so $result_data contains what does $matches (array structure can be different can be 3 dimmensional array not only 2)

Example data: https://eval.in/138817

Note: This question is another approach to get answer which had different data: PHP Regular expression return submatches as array


回答1:


You can use the \G anchor with a global research (preg_match_all):

$pattern = '~(?:office phones|\G(?!\A)) tel\d+ \K\d{4,12}~';
preg_match_all($pattern, $data, $matches);

print_r($matches);

\G is an anchor for the position in the string after the last match, when there is not yet match (at the begining) it is equivalent to the \A anchor.

\K is used to remove the left part of the match from match result.




回答2:


Use positive lookahead (?=.*?home)

<?php

$data = 'office phones tel1 6665555998 tel2 555666888 tel3 555688855 home phones tel1 555222555 tel2 555222444 tel3 555666888';
preg_match_all('/([\d]{2,})(?=.*?home)/', $data, $matches, PREG_PATTERN_ORDER);
print_r($matches[1]);

Array
(
    [0] => 6665555998
    [1] => 555666888
    [2] => 555688855
)

?>

PHP
http://ideone.com/nryjIm

REGEX
http://regex101.com/r/oV7mO2

This is an update based on your comment:

    $pnlist = "office phones tel1 6665555998 tel2 555666888 tel3 555688855 home phones tel1 555222555 tel2 555222444 tel3 555666888";

/*1*/    preg_match_all('/(?:office)(.*?)(?:home)/', $pnlist, $result, PREG_PATTERN_ORDER);
/*2*/    preg_match_all('/([\d]{2,})/', $result[1][0], $pn, PREG_PATTERN_ORDER);

    print_r($pn[1]);

/*
Array ( 
 [0] => 6665555998
 [1] => 555666888
 [2] => 555688855
 ) 
*/

You can change the first preg_match_all start(office) and ending (home) values to whatever you want, then you match the phone numbers on that group.




回答3:


$data = 'office phones tel1 6665555998 tel2 555666888 tel3 555688855 home phones tel1 555222555 tel2 555222444 tel3 555666888';


preg_match_all('/[0-9]{4,12}/', $data,  $matches); // 2nd operation

var_dump($matches);

Like this example



来源:https://stackoverflow.com/questions/23184567/using-regular-expression-subpattern-to-instead-of-using-regular-expression-2-tim

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!