不带锚点的Java中不区分大小写的字符串匹配

时间:2014-10-16 14:34:01

标签: java pattern-matching

注意:这是 NOT 有关不区分大小写匹配的问题。这是一个关于regex锚点的问题。

我在Java中进行基本的不区分大小写的匹配时遇到了很多麻烦:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class match {
    public static void main(String[] args) {
        String prompt="das101.lo1>";
        String str="automate@DAS101.LO1>";

        Pattern ignore = Pattern.compile(prompt.toUpperCase(), Pattern.CASE_INSENSITIVE);
        Matcher mIgn  = ignore.matcher(str);
        if(mIgn.matches())
            System.out.println(str+" Matches " + prompt.toUpperCase());
        else
            System.out.println(str+" Doesn't Match " + prompt.toUpperCase());

        char[] cStr = str.toCharArray();
        char[] cPrompt = prompt.toUpperCase().toCharArray();

        /* Verify that strings match */
        for(int i=cPrompt.length-1, j=cStr.length-1; i>=0 && j>=0 ; --i,--j) {
            if (cPrompt[i]==cStr[j])
                System.out.println("Same: "+ cPrompt[i]+":" + cStr[j]);
            else
                System.out.println("Different: "+ cPrompt[i]+":" + cStr[j]);
        }
    }
}

输出:

samveen@javadev-tahr:/tmp$ javac match.java
samveen@javadev-tahr:/tmp$ java match
automate@DAS101.LO1> Doesn't Match DAS101.LO1>
Same: >:>
Same: 1:1
Same: O:O
Same: L:L
Same: .:.
Same: 1:1
Same: 0:0
Same: 1:1
Same: S:S
Same: A:A
Same: D:D

如果我将if(mIgn.matches())更改为if(mIgn.find()),我会将此简单的字符串模式匹配起作用:

samveen@javadev-tahr:/tmp$ javac match.java
samveen@javadev-tahr:/tmp$ java match
automate@DAS101.LO1> Matches DAS101.LO1>
Same: >:>
Same: 1:1
Same: O:O
Same: L:L
Same: .:.
Same: 1:1
Same: 0:0
Same: 1:1
Same: S:S
Same: A:A
Same: D:D

我哪里错了?

我提到了Case-Insensitive Matching in Java RegExMethods of the Pattern Class

5 个答案:

答案 0 :(得分:5)

String.matches要求整个字符串与模式匹配。好像该模式具有隐含的" ^ ... $"。

Pattern ignore = Pattern.compile(".*" + Pattern.quote(prompt) + ".*",
    Pattern.CASE_INSENSITIVE);

适用于 find 之类匹配。

这可以用原始模式完成:

if (mIgn.find()) {
    System.out.println("Found at position " + mIgn.start());
}

答案 1 :(得分:2)

如果整个字符串与给定模式匹配,则匹配返回true。为此,它的前缀是匹配器' ^'和' $'后缀签名,因此它不会寻找子串。

find()在子字符串匹配的情况下返回true。

看看 - Difference between matches() and find() in Java Regex

答案 2 :(得分:1)

如果整个输入与模式匹配,则

matches()仅返回true,而不是输入的一部分与模式匹配。

输入automate@DAS101.LO1>与完整模式das101.lo1>不匹配。

这解释了使用find()代替matches()时获得的不同结果。

答案 3 :(得分:1)

使用?i正则表达式与.matches进行不区分大小写的匹配:

    // ?i = case insensitive match
    if (mIgn.matches("(?i:str)")) {
        ......
    } else {
        ......
    }

答案 4 :(得分:0)

将此实用程序方法用于不区分大小写的匹配

 // utlity method for mathcesIgonerCase
 public static boolean mathcesIgonerCase(String string1, String sentence){
     return string1.matches("(?i:.*"+sentence+".*)");
 }