我有一个(奇怪的)字符串,如:
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\+):(.*?)/
有人可以提出建议吗?任何帮助表示赞赏!
由于
答案 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
编辑: 如果您想知道哪个关键字导致了拆分,您可以使用此正则表达式:
/((?:EREF\+|MREF\+|CRED\+|SVWZ\+|ABWA\+))(.+?)(?=EREF\+|MREF\+|CRED\+|SVWZ\+|ABWA\+|$)/
它将捕获关键字之间的第一个关键字和文本。