从Begining Pattern(Inclusive)到Next Beginning Pattern(独家)的正则表达式

时间:2017-05-19 22:54:35

标签: regex pcre regex-lookarounds

我想我很擅长RegEx,但这个让我感到难过。搜索字符串看起来像这样......

ISA*lots**of~other~data**with~~no terminating **pattern~ISA*lots**of~other~data**with~~no terminating **pattern~ISA*lots**of~other~data**with~~no terminating **pattern~ISA*lots**of~other~data**with~~no terminating **pattern~
  • 没有换行符。

  • ISA*是一致的起始模式。

  • 字符串的其余部分完全无法预测。

  • 我需要ISA*和所有字符,直到该模式的下一个实例。

我尝试过什么

积极向前看,但这并不能捕获最后的结果。 (ISA\*(.*(?=ISA\*))?)

积极的后视,但我无法弄清楚如何让它变得懒惰。如果它不是懒惰的,那么只有一个匹配。但是如果它是懒惰的,你得到正确数量的匹配,但在模式之后只有一个额外的字符。 ISA\*(?<=ISA\*).*?

另一种解决方案是以编程方式splitexplode字符串,删除第一个(空)结果,然后将分隔符重新附加到每个结果。实际上,这就是我已经拥有的。但是文件的大小,大量的结果以及导致性能问题的后处理。在初步测试中,使用正则表达式似乎可以提供一些有价值的性能提升。

这是用PHP处理的。该字符串来自AS400系统,在&#34; EDI交易&#34;文本文件。我还没有找到任何包含此类文件的工作正则表达式的库。

3 个答案:

答案 0 :(得分:1)

如何使用preg_split

$res = preg_split('/\b(?!^)(?=ISA\*)/', $str);

See php demo at eval.inregex demo at regex101

如果~之前的ISA是可预测的,请使用(?<=~) instead of \b(?!^)

答案 1 :(得分:0)

使用以下基于前瞻性的正则表达式:

ISA\*(.*?)(?=ISA\*|$)

请参阅regex demo

<强>详情:

  • ISA\* - 文字ISA*子字符串
  • (.*?) - 第1组捕获除了换行符之外的任何0 +字符尽可能少(由于懒惰的*?量词)直到(但从匹配中排除)... < / LI>
  • (?=ISA\*|$) - ISA*或字符串结尾(因为它是预测,与模式匹配的文本不会放入返回的匹配值中)。

同一个正则表达式的另一个变体是

ISA\*((?:(?!ISA\*).)*)

请参阅regex demo。展开版本(效率最高):

ISA\*([^I]*(?:I(?!SA\*)[^I]*)*)

请参阅this regex demo

答案 2 :(得分:0)

您也可以尝试表达要捕获的内容:

ISA\*(?:[^I]|I[^S]|IS[^A]|ISA[^*])+

使用preg_match_all