【问题标题】:Multi pattern string split多模式字符串拆分
【发布时间】:2015-08-30 04:28:44
【问题描述】:

我有一个文本,由不同的正则表达式分隔符组成,然后是文本。 在此示例中,我有 3 个正则表达式分隔符(PatternA、B、C),文本如下所示:

|..StringMatchingA..|..Text1..|..StringMatchingB..|..Text2..|..StringMatchingA..|..Text3..|..StringMatchingC..|..Text4. .|

我正在寻找一种高效的 Java 解决方案来将信息提取为三元组列表:

  • {PatternA, StringMatchingA, Text1}
  • {PatternB, StringMatchingB, Text2}
  • {PatternA, StringMatchingA, Text3}
  • {PatternC, StringMatchingC, Text4}

有了这些信息,我知道对于每个三元组,匹配的模式是什么,以及匹配的字符串。

目前,我有这种方法,但我想我可以使用高级正则表达式做一些更有效的事情?

   String pattern = "?=(PatternA|PatternB|PatternC)";
   String()[] tokens = input.split(pattern);
   for(String token : tokens)
   {
      //if start of token matches patternA ...
      //elseif start of token matches pattern B...
      //etc...  
   }

备注:

  • 模式是互斥的。
  • 字符串始终以至少一种模式开头。

【问题讨论】:

  • 如果原始效率是您最关心的问题,那么您可能会发现自定义解析器可以获得更好的性能(一次读取一个字符,直到遇到分隔符,然后返回一个标记)。否则我唯一能建议的就是如果你经常调用split(pattern),就使用private static final Pattern,因为String.split(String)每次调用都会创建一个新的Pattern对象,这在循环中代价高昂。
  • 如果您不知道字符串中每个标记的出现顺序,那么将它们全部交替放置是通常的解决方案((PatternA)|(PatternB)|(PatternC))。但是,尚不清楚这些模式是否互斥,或者是否存在两个可以匹配的字符串。也不清楚您是否希望在某个位置没有任何模式匹配时发生“碰撞”。
  • 我刚刚编辑了帖子:模式是互斥的;我们可以假设字符串以给定模式之一开头。

标签: java regex


【解决方案1】:

您可以使用循环并在代码块内“吃掉”在文本开头找到的内容。 通过这种方式,每次迭代解析都非常简单且可维护/可扩展。

简单的规则是:吃掉你找到的东西并处理它。

像这样的

String chunk;
while(text.size() >0 {

    chunk = eat(text,pattern1);
    if (chunk.lengh()>0}{
       ...
       continue;
    }
    chunk = eat(text,pattern2);
    if (chunk.lengh()>0}{
       ...
       continue;
    }
 }

出于性能原因,您必须在进入循环之前编译正则表达式模式。

(也可以考虑使用解析器生成器,例如ANTLR)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-15
    • 2013-04-11
    • 1970-01-01
    • 2022-07-12
    • 2018-11-10
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多