使用正则表达式子模式而不是在php中使用正则表达式2次

时间:2014-04-20 16:04:20

标签: php regex preg-match preg-match-all

我很感兴趣,如果有可能将包含子模式(子模式)包含到另一个模式中,这个模式允许我将这2个preg_match和preg_match_all转换为一个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)

示例数据:https://eval.in/138817

注意:此问题是获得具有不同数据的另一种方法:PHP Regular expression return submatches as array

3 个答案:

答案 0 :(得分:2)

您可以将\G锚点用于全球研究(preg_match_all):

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

print_r($matches);

\G是最后一次匹配后字符串中位置的锚点,当时还没有匹配(在开始时)它等同于\A锚点。

\K用于从匹配结果中删除匹配的左侧部分。

答案 1 :(得分:0)

使用正向前瞻(?=.*?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

这是基于您的评论的更新:

    $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
 ) 
*/

您可以将第一个preg_match_all开头(办公室)和结束(主页)值更改为您想要的任何值,然后匹配上的电话号码基。

答案 2 :(得分:-1)

$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);

喜欢这个example