返回java正则表达式(单词,空格,特殊字符,双引号)

时间:2013-09-05 04:25:02

标签: java regex text-parsing lexer

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

  • 字词([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".

返回:list,size 8

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

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

"I am_the 2nd best".

返回:list,size 8

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

我希望它能够返回:list,size 2

("I am_the 2nd best", .)

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

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

2 个答案:

答案 0 :(得分:1)

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

\w+

接下来是空白。

\s+

要将字符串作为一个标记进行匹配,您需要允许的字符多于\w。这只允许使用字母数字字符和_,这意味着空格和符号不是。您还需要在方括号外移动起始和结束引号。

不要忘记反斜杠来逃避角色。您希望在字符串中允许\"

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

最后,还有符号。您可以列出所有符号,或者您可以将任何非单词,非空白,非引号字符视为符号。我建议使用后者,这样您就不会选择其他符号,例如@|。所以对于符号:

[^\s\w"]

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

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

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

Pattern pattern = Pattern.compile("\\w+|\\s+|\"(\\\\.|[^\"])+\"|[^\\s\\w\"]");

答案 1 :(得分: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可以完全理解。