【问题标题】:Regex from Begining Pattern (Inclusive) to Next Beginning Pattern (Exclusive)从开始模式(包括)到下一个开始模式(不包括)的正则表达式
【发布时间】:2017-05-19 22:54:34
【问题描述】:

我想我很擅长正则表达式,但这个让我很难过。搜索字符串如下所示...

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 系统,位于“EDI Transaction”文本文件中。我还没有找到任何包含此类文件的工作正则表达式的库。

【问题讨论】:

标签: regex pcre regex-lookarounds


【解决方案1】:

preg_split怎么样

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

See php demo at eval.inregex demo at regex101

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

【讨论】:

    【解决方案2】:

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

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

    regex demo

    详情

    • ISA\* - 文字 ISA* 子字符串
    • (.*?) - 第 1 组尽可能少地捕获除换行符之外的任何 0+ 字符(由于懒惰的 *? 量词)最多(但不包括匹配)...
    • (?=ISA\*|$) - ISA* 或字符串结尾(因为它是前瞻,与模式匹配的文本不会放入返回的匹配值中)。

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

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

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

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

    this regex demo

    【讨论】:

      【解决方案3】:

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

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

      使用preg_match_all

      【讨论】:

        猜你喜欢
        • 2023-03-31
        • 1970-01-01
        • 2023-04-09
        • 1970-01-01
        • 2016-11-28
        • 1970-01-01
        • 2015-11-05
        • 1970-01-01
        • 2011-04-20
        相关资源
        最近更新 更多