java matcher.matches()始终为false

au9on6nz  于 11个月前  发布在  Java
关注(0)|答案(3)|浏览(109)

我试着做一个卡塔代码,它应该很容易,但我不知道为什么它不工作。这个练习的目标是将一个字符串转换为一个新字符串,其中新字符串中的每个字符都是"(",如果该字符在原始字符串中只出现一次,或者")",如果该字符在原始字符串中出现多次。在确定字符是否重复时忽略大写。
我测试的代码是:

public class Kata {

    public static void main(String[] args) {
        String t = "recede";
        System.out.println(Kata.encode(t));
    }

    public static String encode(String word){
        StringBuilder result = new StringBuilder();
        char[] arr = word.toCharArray();
        for (char c : arr) {
            Pattern pattern = Pattern.compile("^[" + c  
                    + String.valueOf(c).toUpperCase() 
                    + "]{2,}+$");
            Matcher matcher = pattern.matcher(word);
            if (matcher.matches()) 
                result.append(")");
            else 
                result.append("(");
        }
        return result.toString();
    }
}

字符串
我尝试将matches()改为find(),并始终写入"((((((",并且在debug中始终在if条件中匹配false。
此外,我想说的是,我尝试了其他模式,但结果相同,比如"[" + c + String.valueOf(c).toUpperCase() + "]{2,}",我知道其他方法来创建Kata,但我想知道为什么模式和匹配器失败,因为这不是第一次在Java中发生,在其他语言中,我没有遇到这样的问题。

tct7dpnv

tct7dpnv1#

为什么您的解决方案不起作用:

  • 您正在建立错误的模式。^[cC]{2,}+$只会比对包含两个或多个cC字符的字串。若要比对包含两个cC字母的字串,您需要类似(?i)c.*c(?i)c.*?c或更好的(?i)c[^c]*c模式。
  • .matches()方法需要一个完整的字符串匹配,所以模式中的锚点是多余的。像(?i)c[^c]*c这样的正则表达式需要使用Matcher.find()来查找字符串中的任何匹配。

因此,您可以使用

for (char c : arr) {
    Pattern pattern = Pattern.compile("(?i)" + c + "[^"  + c + "]*"  + c);
    Matcher matcher = pattern.matcher(word);
    if (matcher.find()) 
        result.append(")");
    else 
        result.append("(");
}

字符串
请参阅this Java demo。如果您需要支援特殊字符,可以使用Pattern.compile("(?i)" + Pattern.quote(c) + "[^" + Pattern.quote(c) + "]*" + Pattern.quote(c))
或者,在没有正则表达式的情况下:

for (char c : arr) {
    if (word.toUpperCase().chars().filter(ch -> ch == Character.toUpperCase(c)).count() > 1) 
        result.append(")");
    else 
        result.append("(");
}


请参见this Java demo

qojgxg4l

qojgxg4l2#

这里不需要正则表达式,只需要填充一个频率图。你应该预先计算重复。

import java.util.HashMap;
import java.util.Map;

public class Kata {
    public static void main(String[] args) {
        String t = "recede";
        System.out.println(encode(t)); // "()()()"
    }

    public static String encode(String word) {
        Map<Character, Integer> frequency = new HashMap<>();
        for (char ch : word.toCharArray()) {
            frequency.merge(Character.toLowerCase(ch), 1, Integer::sum);
        }
        StringBuilder result = new StringBuilder(word.length());
        for (char ch : word.toCharArray()) {
            result.append(frequency.get(Character.toLowerCase(ch)) > 1 ? ')' : '(');
        }
        return result.toString();
    }
}

字符串

sbtkgmzw

sbtkgmzw3#

最后,在Wiktor Stribizew的评论之后,我可以更多地理解我对正则表达式的困惑,并找到一个更好或更干净的表达式。最终的代码是:

public static String encode(String word){
            StringBuilder result = new StringBuilder();
            char[] arr = word.toCharArray();
        for (char c : arr) {
            Pattern pattern = Pattern.compile("(?i)" + "(.*" + c + ".*){2,}");
            Matcher matcher = pattern.matcher(word);
            result.append(matcher.find() ? ")" : "(");
        }

            return result.toString();
    }

字符串

相关问题