JAVA:用户定义标记的正则表达式

时间:2013-04-05 11:39:17

标签: java regex customization

我需要在一组用户定义的标记上运行regexp。

例如,我有一个这样的字符串:     TOK3 TOK1 TOK2 TOK2 TOK4 TOK3 //示例字符串

并使用这样的正则表达式:   (TOK1|TOK2)+ // regexp

我想在我的示例字符串中捕获令牌序列:TOK1 TOK2 TOK2

现在, regexp 通常可以处理一系列字符,所以我的问题略有不同,因为我的标记不是字符而是字符串。我的令牌可以由两个或更多个字符组成。此外,我的软件应该能够检测到示例中的正则表达式匹配位置(1,4)处的字符串。

目前,我通过将每个标记映射到ASCII字母表中的字符并在删除空格后运行正则表达式来解决问题。

然而,我并没有完全满意这个解决方案,我想知道是否有更好的解决方案。谢谢!

修改

正则表达式中的空格仅用于分隔标记。它们并不意味着令牌之间必须有空格。

2 个答案:

答案 0 :(得分:3)

按照你的例子,这应该可以正常工作:

(?:(?:TOK1|TOK2|...)(?: |$))+

Matcher #start方法会为您提供比赛开始的位置。

尽管如此,我觉得我在你的问题中遗漏了一些东西......

答案 1 :(得分:1)

如何存储所有空格的位置并使用它来将字符串位置转换为标记位置?

远不像直接的正则表达式那样优雅,但这是一个想法。

TreeMap<Integer, Integer> spaces = new TreeMap<Integer, Integer>();
String regex = "(?<=^| )((TOK1|TOK2)( |$))+";
String str = "TOK3 TOK1 TOK2 TOK2 TOK4 TOK3";
int c = 0;
spaces.put(0, 0);
for (int i = 0; i < str.length(); i++)
{
   if (str.charAt(i) == ' ')
     spaces.put(i, ++c);
}
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
while (m.find()) {
   System.out.println(m.group());
   System.out.println("start = " + spaces.floorEntry(m.start()).getValue());
   System.out.println("finish = " + spaces.floorEntry(m.end()).getValue());
}

另一种选择是String.split

String str = "TOK3 TOK1 TOK2 TOK2 TOK4 TOK3";
String[] arr = str.split(" "); // maybe consider using \\s or \\s+ instead
int start = -1;
String match = "";
for (int i = 0; i < arr.length; i++)
{
   if (arr[i].matches("(TOK1|TOK2)"))
   {
      if (start == -1)
         start = i;
      match += ((match.length() != 0) ? " " : "") + arr[i];
   }
   else if (start != -1)
   {
      System.out.println(match);
      System.out.println("start = " + start);
      System.out.println("finish = " + i);
      match = "";
      start = -1;
   }
}