PHP如何获取某些关键字之间的子字符串

时间:2016-10-06 20:39:41

标签: php regex string

我有一个(奇怪的)字符串,如:

EREF+012345678901234MREF+ABCDEF01234567890123CRED+DE12ABC01234567890SVWZ+ABCEDFG HIJ 01234567890 123,45ABWA+ABCDEFGHIJKLMNOPQR

我需要查找的模式只能由关键字定义:EREF+MREF+CRED+等。我知道有19个关键字,但字符串可能包含这19个关键字的不同子集。我不知道订单是否保持不变,我可以告诉EREF+很可能是第一个关键字,但订单也可能不同。我也不知道19个关键字中哪一个可能是字符串中的最后一个,因为这可能会逐个变化。

我的第一种方法是使用explode()两次,使用关键字1和关键字2 - 但如果关键字改变顺序(我不能保证它们不会),我将不得不经历所有可能的组合。

无论如何,这是我使用的第一个(工作)代码:

<?php 

$string = "EREF+012345678901234MREF+ABCDEF01234567890123CRED+DE12ABC01234567890SVWZ+ABCEDFG HIJ 01234567890 123,45ABWA+ABCDEFGHIJKLMNOPQR";

function getBetween($content,$start,$end){
    $r = explode($start, $content);
    if (isset($r[1])){
        $r = explode($end, $r[1]);
        return $start.$r[0];
    }
    return '';
}

$start = "EREF+";
$end = "MREF+";
$output = getBetween($string,$start,$end);
echo $output;

?>

所以现在我正在寻找正则表达式来提出一个解决方案,它提取两个关键字之间的子字符串,其中任何关键字可以是起始分隔符,而任何其他关键字可能是结束分隔符。

由于周围有数以千计的正则表达式问题,我花了一些时间尝试适应其他解决方案,但直到现在都没有成功。我必须承认正则表达式是伏都教给我,我似乎不能记住这些模式超过一分钟。我发现this thread与我想要实现的非常接近,并尝试了一些调整,但我无法让它正常工作。

到目前为止,这是我的代码:

<?php 

$string = "EREF+012345678901234MREF+ABCDEF01234567890123CRED+DE12ABC01234567890SVWZ+ABCEDFG HIJ 01234567890 123,45ABWA+ABCDEFGHIJKLMNOPQR";

$matches = array();
$keywords = ['EREF+', 'MREF+', 'CRED+', 'SVWZ+', 'ABWA+'];
$pattern = sprintf('/(?:%s):(.*?)/', join('|', array_map(function($keyword) {
    return preg_quote($keyword, '/');
}, $keywords)));

preg_match_all($pattern, $string, $matches);

print_r($matches);

?>

...而构建的模式看起来像这样:

/(?:EREF\+|MREF\+|CRED\+|SVWZ\+|ABWA\+):(.*?)/

有人可以提出建议吗?任何帮助表示赞赏!

由于

1 个答案:

答案 0 :(得分:1)

您可以使用此正则表达式:

/(?<=EREF\+|MREF\+|CRED\+|SVWZ\+|ABWA\+)(.+?)(?=EREF\+|MREF\+|CRED\+|SVWZ\+|ABWA\+|$)/

它将匹配已定义关键字之间的字符串。

(?<=EREF\+|MREF\+|CRED\+|SVWZ\+|ABWA\+) # look backward for a keyword
(.+?) #Match any character, non greedy
(?=EREF\+|MREF\+|CRED\+|SVWZ\+|ABWA\+|$) # Look forward for a keyword or end of string

Regex101

编辑: 如果您想知道哪个关键字导致了拆分,您可以使用此正则表达式:

/((?:EREF\+|MREF\+|CRED\+|SVWZ\+|ABWA\+))(.+?)(?=EREF\+|MREF\+|CRED\+|SVWZ\+|ABWA\+|$)/

它将捕获关键字之间的第一个关键字和文本。

Live sample