我想单独使用正则表达式来解决以下问题:一个多行字符串,其中一端的信息由Z!
隔开,另一端的S0634
隔开,如:
Z! EXT .000 ...HOUSE... L24JN7
PERSONAL COMPUTER\J\039060-L24JN7-000-*****-*****-
Payroll No.: 1
-Name:
-Folios:
-Date: 6/24/2014
-Subformat: S0634
Z! EXT .000 ...HOUSE... L24JN7
PERSONAL COMPUTER\J\039060-L24JN7-000-*****-*****-
Payroll No.: 2
-Name:
-Date: 6/24/2014
-Subformat: S0634
Z! EXT .000 ...HOUSE... L24JN7
PERSONAL COMPUTER\J\039060-L24JN7-000-*****-*****-
Payroll No.: 3
-Name:
-Folios:
-Date: 6/24/2014
-Subformat: S0634
desired content.</li>
我想只捕获由提到的双字符序列限定的组,并且包含单词Folios
(中间的一个组没有它,只有2个组。)
我知道如何拆分成组并且还可以返回不拥有它的组(例如(Z!\s*EXT(?:(?!-Folios:).)*?S0634)
)。但是,如何捕获做的群组让我无法理解。我只对正则表达式单行代码解决方案感兴趣(我知道我可以反汇编成组然后检查每个组)。
答案 0 :(得分:4)
使用此:
$regex = '~(?sm)Z!(?:(?!S0634).)*?Folios.*?S0634~';
preg_match_all($regex, $yourstring, $matches);
// See all matches
print_r($matches[0]);
在the demo中,您可以看到中间组被排除在外。
<强>输出:强>
Array
(
[0] => Z! EXT .000 ...HOUSE... L24JN7
PERSONAL COMPUTER\J9060-L24JN7-000-*****-*****-
Payroll No.: 1
-Name:
-Folios:
-Date: 6/24/2014
-Subformat: S0634
[1] => Z! EXT .000 ...HOUSE... L24JN7
PERSONAL COMPUTER\J9060-L24JN7-000-*****-*****-
Payroll No.: 3
-Name:
-Folios:
-Date: 6/24/2014
-Subformat: S0634
)
<强>解释强>
(?s)
激活DOTALL
模式,允许点跨行匹配(?m)
启用了多行模式,允许^
和$
在每一行匹配Z!
匹配起始分隔符(?:(?!S0634).)*?
懒惰地匹配S0634
未跟随的任何字符,最多... Folios
.*?S0634
懒洋洋地匹配字符串的其余部分,直至结束分隔符<强>参考强>
答案 1 :(得分:2)
您可以使用此模式执行此操作:
Z!(?>(?!Z!).*\R)+?\s*-Folios:(?>(?!Z!).*\R)*?.* S0634
(?!Z!)
以避免匹配具有Folios
的下一个群组。这可确保Folios
和S0634
位于同一组中。