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
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.
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.
$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