使用文件中相似行的字符串,
03/21/19 11:20 LOC3 UNA:
03/21/19 11:40 LOC2 IN: NEW BD PN VO LVA
03/21/19 11:50 LOC3 OFF:
03/21/19 12:20 LOC2 IN: OLD XD AB VO LVA
我需要从石灰1中捕获NEW,BD,PN,VO,LVA,并在第2行中捕获OLD,XD,AB,VO,LVA等,而忽略其他行
这只会选择最后一个“ VO”字眼
IN:\s(([^\s]+)\s+)+.*LVA
答案 0 :(得分:3)
使用
,您可以匹配在特定文本之后在字符串中还有一些文本的情况下,出现非空白文本块preg_match_all('~(?:\G(?!\A)(?=.*LVA)|IN:)\h+\K\S+~', $s, $matches)
请参见regex demo
详细信息
(?:\G(?!\A)(?=.*LVA)|IN:)
-上一个匹配项的末尾(在行号以外的0+个字符之后的字符串中,LVA
位于字符串的后面)或IN:
子字符串(基本上,这意味着匹配IN:
之后但满足LVA
之后的模式的连续子字符串)\h+
-1个以上水平空格\K
-匹配重置运算符\S+
-1个以上非空格字符。PHP:
$s = "03/21/19 11:20 LOC2 IN: NEW BD PN VO LVA";
if (preg_match_all('~(?:\G(?!\A)(?=.*LVA)|IN:)\h+\K\S+~', $s, $matches)) {
print_r($matches[0]);
}
// => Array ( [0] => NEW [1] => BD [2] => PN [3] => VO [4] => LVA )
要获得多个匹配项,请在具有捕获组的第一个非捕获组中包装模式,然后在构建最终输出时检查子匹配项。像
$s = "03/21/19 11:20 LOC2 IN: NEW BD PN VO LVA
03/21/19 11:20 LOC2 IN: NEW BD PN VO LVA VB";
$res = [];
if (preg_match_all('~(?:\G(?!\A)(?=.*LVA)|(IN:))\h+\K\S+~', $s, $matches, PREG_SET_ORDER, 0)) {
$tmp = [];
foreach ($matches as $r) {
if (count($r) > 1) {
if (count($tmp)>0) {
$res[] = $tmp;
$tmp = [];
}
}
$tmp[] = $r[0];
}
if (count($tmp)>0) {
$res[] = $tmp;
}
}
print_r($res);
// => Array (
// [0] => Array ( [0] => NEW [1] => BD [2] => PN [3] => VO [4] => A )
// [1] => Array ( [0] => NEW [1] => BD [2] => PN [3] => VO [4] => LVA )
// )
请参见PHP demo。
答案 1 :(得分:0)
如果字符串始终具有相同的模式,则可以使用预算解决方案,方法是在新行和": "
上进行爆炸并获取最后一个值。
$str = "03/21/19 11:20 LOC2 IN: NEW BD PN VO LVA
03/21/19 11:20 LOC2 IN: OLD XD AB VO LVA";
foreach(explode("\n", $str) as $line){
$tmp = explode(": ", $line);
$result[] = end($tmp);
}
var_dump($result);