多模式字符串分割

4

我有一段文本,由不同的正则表达式分隔符组成,后跟着文本。在这个例子中,我有三个正则表达式分隔符(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对象,在循环中这是代价高昂的。 - Bobulous
如果您不知道字符串中每个标记的出现顺序,则将它们全部放在交替项中是通常的解决方案((PatternA)|(PatternB)|(PatternC))。然而,这些模式是否互斥并不清楚,或者是否存在一个字符串可以匹配其中两个模式也不清楚。同样不清楚的是,在某个位置上没有任何模式匹配时是否要进行“碰撞”。 - nhahtdh
我刚刚编辑了帖子:模式是互斥的;我们可以假设字符串以给定的模式之一开头。 - David
1个回答

0
你可以使用循环,在代码块内部“吃掉”文本开头的内容。这样,在每次迭代中,解析就变得非常简单和可维护/可扩展。
简单的规则是:吃掉你找到的并处理它。
类似于这样的东西。
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)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接