簡體   English   中英

如何檢查正則表達式匹配是否可以用盡字符串?

[英]How to check if a string can be exhausted by regex matches?

因此,問題在於確定字符串中的每個字符是否將包含在特定正則表達式的匹配項中。 或者,換句話說,如果可以包含在特定正則表達式的某些匹配中的所有字符位置的集合包括字符串中的所有字符位置。

我的想法是做這樣的事情:

boolean matchesAll(String myString, Matcher myMatcher){
    boolean matched[] = new boolean[myString.size()];
    for(myMatcher.reset(myString); myMatcher.find();)
        for(int idx = myMatcher.start(); idx < myMatcher.end(); idx++)
            matched[idx] = true;

    boolean allMatched = true;
    for(boolean charMatched : matched)
        allMatched &= charMatched;

    return allMatched
}

但是,有更好的方法嗎?

另外,在我寫這篇文章時,我發現在某些情況下,這並不能滿足我的需求

matchesAll("abcabcabc", Pattern.compile("(abc){2}").matcher()); //returns false

因為Matcher僅嘗試從最后一場比賽的結尾開始進行比賽。 我希望它返回true,因為如果在位置3啟動匹配器,則它可能在匹配中包含第三個abc

boolean matchesAll(String myString, Matcher myMatcher){

    boolean matched[] = new boolean[myString.size()];
    boolean allMatched = true;

    for(int idx = 0; idx < myString.size() && myMatcher.find(idx);
            idx = myMatcher.start() + 1) {

        for(int idx2 = myMatcher.start(); idx2 < myMatcher.end(); idx2++)
            matched[idx2] = true;
    }

    boolean allMatched = true;
    for(boolean charMatched : matched)
        allMatched &= charMatched;

    return allMatched;
}

有什么方法可以使此代碼更好,更快或更易讀?

我為您提供2個答案,盡管我不確定我是否理解正確的問題。

  1. 調用Pattern.matcher(str2match).matches()方法,而不是find()。 一次返回一個真實的返回值將告訴您整個字符串是否匹配。
  2. 在reg exp前面加上“ ^”(字符串的開頭),並在“ Pattern.compile(str)”之前的正則表達式之前(在字符串的末尾)添加一個“ $”。

這兩種解決方案也可以一起使用。 下面是一個示例類-您可以將其復制到AllMatch.java中,使用“ javac AllMatch.java”進行編譯,然后以“ java AllMatch”運行(我假設您的CLASSSPATH中包含“。”)。 只需選擇您認為更優雅的解決方案即可:)新年快樂!

import java.util.regex.Pattern;

公共類AllMatch {

private Pattern pattern;

public AllMatch (String reStr) {
    pattern = Pattern.compile ("^" + reStr + "$");
}

public boolean checkMatch (String s) {
    return pattern.matcher(s).matches();
}

    public static void main (String[] args) {
    int n = args.length;
    String  rexp2Match = (n > 0) ? args[0] : "(abc)+",
        testString = (n > 1) ? args[1] : "abcabcabc",
        matchMaker = new AllMatch (rexp2Match)
                .checkMatch(testString) ? "" : "un";
    System.out.println ("[AllMatch] match " + matchMaker +
                "successful");
    }

}

這有效:

private static boolean fullyCovered(final String input,
    final Pattern pattern)
{
    // If the string is empty, check that it is matched by the pattern
    if (input.isEmpty())
        return pattern.matcher(input).find();

    final int len = input.length();
    // All initialized to false by default
    final boolean[] covered = new boolean[len];

    final Matcher matcher = pattern.matcher(input);

    for (int index = 0; index < len; index++) {
        // Try and match at this index:
        if (!matcher.find(index)) {
            // if there isn't a match, check if this character is already covered;
            // if no, it's a failure
            if (!covered[index])
                return false;
            // Otherwise, continue
            continue;
        }
        // If the match starts at the string index, fill the covered array
        if (matcher.start() == index)
            setCovered(covered, index, matcher.end());
    }

    // We have finished parsing the string: it is fully covered.
    return true;
}

private static void setCovered(final boolean[] covered,
    final int beginIndex, final int endIndex)
{
    for (int i = beginIndex; i < endIndex; i++)
        covered[i] = true;
}

它可能不會更快地執行,但是我想它更容易閱讀;)而且, .find(int)重置匹配器,因此這是安全的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM