0

说有一句话

那个山姆-我-是

两个单词以相同的序列“am”结尾,其中第二个序列是最后一个单词。

我需要编写一个正则表达式来匹配这样一个句子,其中的序列可以是任何字母串。

语言是Java。我不太明白的是如何在一个句子中匹配某些内容而忽略其余部分。

这是 Java 测试的准备问题。

谢谢你。

这是我用来测试的代码

public static void doMatching(){

    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

    try {

        String pattern, s;
        System.out.print("Pattern: ");
        pattern = in.readLine();
        while (!pattern.equals("quit")){
            System.out.print("String: ");
            s = in.readLine();
            System.out.println(Pattern.matches(pattern, s));
            System.out.print("Pattern: ");
            pattern = in.readLine();
        }
        } catch (IOException e){
            System.out.println("Error!");
    } catch (Exception e2){
        System.out.println("Unknown!");
    }

}


public static void main(String[] args) {
    // TODO code application logic here

    doMatching();
}

这是结果

Pattern: (\\w+\\b).*\\b\\1$
String: that sam-i-am
false
4

3 回答 3

3

您正在搜索的正则表达式是:

(\w+\b).*\b\1$

这也包括一个下划线作为一个字母,如果你需要排除你可以使用[a-zA-Z]

\w匹配任何字母
+与前一个表达式匹配 1 次或多次,以贪婪的方式
\b匹配单词边界。这是一个零宽度匹配。
()分组并保存结果,以便您以后可以使用它作为反向引用
.匹配除换行符之外的任何内容
*与前一个表达式匹配 0 次或多次,以贪婪的方式
\1是第一个反向引用,它匹配捕获的第一件事()
$是零宽度匹配在字符串的末尾。

零宽度匹配是实际上不包含任何字符的匹配。

于 2012-11-13T23:45:59.500 回答
3
"(\\w+\\b).*\\b\\1$"

这将匹配单词末尾的一些重要的单词字符,(\\w+\\b)并确保它们在字符串末尾匹配为一个完整的单词。

于 2012-11-13T23:46:51.533 回答
0

这里还有其他很好的答案,但我认为这仍然更合适:

([a-zA-Z]+)\b.+\b\1$

也许会让人费解,但对于 RegEx,尽可能简洁和深思熟虑是个好主意。

这里的字符范围似乎比\w问题的性质要好。我认为最好将第一个单词边界移到捕获组之外。和.+vs..*因为必须至少存在一个非单词字符(尽管.*结合单词边界几乎肯定也会匹配)。

于 2012-11-14T00:04:38.100 回答