4

我正在尝试在 Java 中匹配包含单词"#SP"(无引号,不区分大小写)的字符串。但是,我发现使用正则表达式非常困难!

我需要匹配的字符串: "This is a sample #sp string", "#SP string text...", "String text #Sp"

我不想匹配的字符串: "Anything with #Spider", "#Spin #Spoon #SPORK"

到目前为止,这是我所拥有的:http: //ideone.com/B7hHkR。有人可以指导我构建我的正则表达式吗?

我也试过:"\\w*\\s*#sp\\w*\\s*"无济于事。

编辑:这是来自 IDEone 的代码:

java.util.regex.Pattern p = 
    java.util.regex.Pattern.compile("\\b#SP\\b", 
        java.util.regex.Pattern.CASE_INSENSITIVE);

java.util.regex.Matcher m = p.matcher("s #SP s");

if (m.find()) {
    System.out.println("Match!");
}
4

3 回答 3

5

(编辑:不需要正面向后看,只完成匹配,而不是替换)

您是 Java 错误命名的正则表达式匹配方法的另一个受害者。

.matches()非常不幸的是,它试图匹配整个输入,这明显违反了“正则表达式匹配”的定义(正则表达式可以匹配输入中的任何位置)。您需要使用的方法是.find().

这是一个脑残的 API,不幸的是,Java 并不是唯一具有这种被误导的方法名称的语言。Python也认罪。

此外,您遇到的问题\\b将在单词边界上检测到并且#不是单词的一部分。您需要使用交替检测输入的开头或空格。

您的代码需要看起来像这样(非完全限定的类):

Pattern p = Pattern.compile("(^|\\s)#SP\\b", Pattern.CASE_INSENSITIVE);

Matcher m = p.matcher("s #SP s");

if (m.find()) {
    System.out.println("Match!");
}
于 2012-12-20T22:59:51.540 回答
4

你做得很好,但 # 前面的 \b 具有误导性。\b 是单词边界,但# 已经不是单词字符(即它不在集合[0-9A-Za-z_] 中)。因此,# 之前的空格不被视为单词边界。改成:

java.util.regex.Pattern p = 
    java.util.regex.Pattern.compile("(^|\\s)#SP\\b", 
        java.util.regex.Pattern.CASE_INSENSITIVE);

(^|\s) 表示:匹配 ^ 或 \s,其中 ^ 表示字符串的开头(例如“#SP String”),\s 表示空白字符。

于 2012-12-20T23:17:42.500 回答
1

正则表达式"\\w*\\s*#sp\\w*\s*"将匹配 0 个或多个单词,然后是 0 个或多个空格,然后是 #sp,然后是 0 个或多个单词,然后是 0 个或多个空格。我的建议是不要使用 \s* 来分解你的表达中的单词,而是使用 \b。

"(^|\b)#sp(\b|$)"
于 2012-12-20T22:59:49.430 回答