0

我正在尝试使用 java regex 来标记任何语言源文件。我希望列表返回的是:

  • 词([a-z_A-Z0-9]
  • 空间
  • 任何[()*.,+-/=&:]一个字符
  • 和引用的项目留在引号中。

这是我到目前为止的代码:

Pattern pattern = Pattern.compile("[\"(\\w)\"]+|[\\s\\(\\)\\*\\+\\.,-/=&:]");

Matcher matcher = pattern.matcher(str);
List<String> matchlist = new ArrayList<String>();

while(matcher.find()) {
    matchlist.add(matcher.group(0));
}

例如,

"I" am_the 2nd "best".

返回:列表,大小 8

("I", ,am_the, ,2nd, ,"best", .)

这就是我想要的。但是,如果引用整个句子,句号除外:

"I am_the 2nd best".

返回:列表,大小 8

("I, ,am_the, ,2nd, ,best", .)

我希望它能够返回:列表,大小 2

("I am_the 2nd best", .)

如果这是有道理的。我相信它适用于我想要的一切,除了返回字符串文字(我想保留引号)。我从允许我实现这一目标的模式中遗漏了什么?

无论如何,如果有一个我看不到的更容易使用的模式,请帮助我。上面显示的模式是许多试验/错误的编译。非常感谢您的任何帮助。

4

2 回答 2

1

首先,您需要将单词匹配代码与字符串文字匹配代码分开。对于单词匹配,使用:

\w+

接下来是空格。

\s+

要将字符串作为一个标记进行匹配,您需要允许更多字符,而不仅仅是\w. 这只允许字母数字字符 and _,这意味着不允许空格和符号。您还需要将开始和结束引号移到方括号之外。

并且不要忘记使用反斜杠来转义字符。您想允许\"在字符串内部。

"(\\.|[^"])+"

最后,还有符号。您可以列出所有符号,或者您可以将任何非单词、非空白、非引号字符视为符号。我推荐后者,这样您就不会被其他符号(如@|. 所以对于符号:

[^\s\w"]

将这些部分放在一起,我们得到了这个组合的正则表达式:

\w+|\s+|"(\\.|[^"])+"|[^\s\w"]

或者,正确转义所有内容,以便将其放入源代码中:

Pattern pattern = Pattern.compile("\\w+|\\s+|\"(\\\\.|[^\"])+\"|[^\\s\\w\"]");
于 2013-09-05T23:51:47.527 回答
0

通常,在解析文本时,您所描述的过程称为“词法分析”,使用的函数称为“词法分析器”,用于将输入流分解为可识别的标记,如单词、数字、空格、句点等.

词法分析器的输出由“解析器”使用,该解析器通过识别属于一起的标记组来进行“句法分析”,例如 [双引号] [单词] [双引号]。

我建议您遵循相同的两遍策略,因为它已在许多解析器中一次又一次地得到证明。

所以,你的第一步可能是使用这个正则表达式作为你的词法分析器:

\W|\w+

这会将您的输入文本分解为单个非单词字符(如空格、双引号和单引号、逗号、句点等)或一个或多个单词字符的序列,其中\w实际上只是[a-zA-Z_0-9].

因此,使用上面的示例:

String str=/"I" am_the 2nd "best"./

String p="\\W|\\w+"

Pattern pattern = Pattern.compile(p);
Matcher matcher = pattern.matcher(str);
List<String> matchlist = new ArrayList<String>();

while(matcher.find()) {
    matchlist.add(matcher.group(0));
}

产生:

['"', 'I', '"', ' ', 'am_the', ' ', '2nd', ' ', '"', 'best', '"', '.']

然后您可以决定如何在您的代码中处理。

不,这并没有给你一个万能的正则表达式来匹配你上面列出的两种情况,但根据我的经验,正则表达式并不是进行这种句法分析的最佳工具您需要,因为它们要么缺乏涵盖所有可能情况所需的表达能力,要么,而且更有可能的是,它们很快变得过于复杂,但真正的 RegExp maven 无法完全理解。

于 2013-09-06T00:22:30.313 回答