0

我需要在一组用户定义的令牌上运行正则表达式。

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

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

我想捕获标记序列:TOK1 TOK2 TOK2在我的示例字符串中。

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

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

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

编辑

正则表达式中的空格仅用于分隔标记。它们并不真正意味着令牌之间的空格是强制性的。

4

2 回答 2

3

按照您的示例,这应该可以正常工作:

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

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

尽管如此,因为它看起来很容易,我觉得我在你的问题中遗漏了一些东西......

于 2013-04-05T12:06:28.310 回答
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;
   }
}
于 2013-04-05T12:47:32.043 回答