捕获由单词绑定并包含某些单词的组

时间:2014-07-04 00:01:27

标签: regex pcre autoit regex-lookarounds

我想单独使用正则表达式来解决以下问题:一个多行字符串,其中一端的信息由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))。但是,如何捕获的群组让我无法理解。我只对正则表达式单行代码解决方案感兴趣(我知道我可以反汇编成组然后检查每个组)。

2 个答案:

答案 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的下一个群组。这可确保FoliosS0634位于同一组中。