正则表达式,在一个句子中匹配两个序列

时间:2012-11-13 23:36:11

标签: java regex

说有句子

  

Sam-I-am

两个单词以相同的序列“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

3 个答案:

答案 0 :(得分:3)

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

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

如果您需要排除可以使用[a-zA-Z]

,则还包括下划线作为字母

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

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

答案 1 :(得分:3)

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

这将匹配单词(\\w+\\b)末尾的一些非平凡数量的单词字符,并确保它们在字符串末尾匹配为完整单词。

答案 2 :(得分:0)

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

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

也许分裂头发,但使用RegEx,尽可能简洁和慎重是一个好主意。

由于问题的性质,此处的字符范围似乎优于\w。我认为最好将第一个单词边界移到捕获组之外。 .+.*因为必须至少存在一个非单词字符(尽管.*与单词边界相结合几乎肯定会匹配)。