【问题标题】:Is there such a thing as a wildcard character in Java?Java中有通配符这样的东西吗?
【发布时间】:2011-02-10 14:13:27
【问题描述】:

我正在运行一个比较程序,此时它会进行直接的“字符串到字符串”比较,如果它们完全匹配,它会输出它们是匹配的。

嗯,我希望添加一个允许“相似性”的附加功能......

例如:

String em1 = "52494646";
String em2 = "52400646";


if (em1.equals(em2)){
    output.writeUTF(dir + filenames[i]);
}

这有点像代码的 sn-p。我希望它跳过“00”并仍然将其识别为“几乎”相同的数字并仍然输出它。

我想它看起来像 String em2 = "524"+ ## +"646" 但这显然只是一个概念

有谁知道是否有办法获得这种“通配符”(我从 uni SQL 中提取的一个术语),或者是否有另一种方法来进行这种相似类型的交易。

谢谢:)

【问题讨论】:

    标签: java comparison wildcard


    【解决方案1】:

    你可以使用正则表达式:

    if (em1.matches("524[0-9]{2}646")) {
      // do stuff
    }
    

    有关 Java 特定文档,请参阅 the Pattern class。对于正则表达式的一些使用(如上例),String中有快捷方式:matches()replaceAll()/replaceFirst()split()

    regular-expressions.info 通常有关于正则表达式的良好文档。

    【讨论】:

    • 这也可以用字母来完成,就像在 A-F 十六进制字符中一样?
    • 是的,regular expressions 可以做到这一点并且更多(请参阅regular-expressions.info 了解有关正则表达式的一些非常好的信息)。
    • 大概我需要下载这个正则表达式的东西?还是它附带标准的 Java 开发工具包?
    • @user:正则表达式从 1.4 开始就成为 Java 的一部分(并且在此之前作为第三方库提供)。请参阅Pattern class
    【解决方案2】:

    您可以使用正则表达式轻松解决:

    if (em1.matches("524..646"))
    

    例如。

    . 是代表any character 的通配符。如果您想将通配符限制为数字,可以将其替换为\\d。)

    这是一个更通用的变体,可以将“0”与任何字符匹配:

    String em1 = "52494646";
    String em2 = "52400646";
    
    if (em1.matches(em2.replaceAll("0", "\\\\d"))){
        System.out.println("Matches");
    }
    

    【讨论】:

      【解决方案3】:

      通常您可以组合使用startsWith、endsWith 或contains 来查找字符串是否以另一个字符串开头、结尾或包含另一个字符串。您可以将这些组合使用,例如

      number.startsWith("524") && number.endsWith("646");
      

      在 95% 的情况下,使用正则表达式可能是更好的选择,但成本更高。

      【讨论】:

        【解决方案4】:

        我认为上述 RE 解决方案的问题在于,您对第三或第四位相同的数字不感兴趣,但对一位/两位数字相同的数字不感兴趣。

        这是一个更复杂的问题,但您基本上想为您的两个字符串计算 http://en.wikipedia.org/wiki/Hamming_distance。众所周知的算法可以解决很多问题,所以你应该找到很多例子,但我担心标准库不会这样做。它也是一个 for 循环和一个计数器,所以你不应该在实现时遇到问题 - 你失去了 STL 可以使用的一些优化潜力(比较两个字符串的地址,你必须在任何一种情况下比较整个字符串),但仅此而已。

        【讨论】:

          【解决方案5】:

          正则表达式将是您想要执行此操作的方式。对于您的示例,您需要类似"524\\d{2}646" 的内容。请参阅Java API for Regex

          还可以在此处查看有用的 Apache Commons IO 库,因为听起来您正在处理文件:https://commons.apache.org/proper/commons-io/javadocs/api-release/index.html?org/apache/commons/io/package-summary.html

          【讨论】:

            【解决方案6】:

            您应该为此使用Regular Expressions

            【讨论】:

              【解决方案7】:

              好吧,不幸的是,我相信 apache commons StringUtil 没有任何通配符操作。

              如果我没记错的话,mysql JDBC 连接器上有一个 StringUtils 类,它有一个比较字符串和通配符的方法。

              -或者-

              您可以尝试使用一些模糊逻辑:http://jfuzzylogic.sourceforge.net/html/index.html

              【讨论】:

                【解决方案8】:

                为什么人们不愿意只写一个简单直接的算法?

                boolean equals(String s1, String s2, char wildcard)
                
                    if(s1.length() != s2.length()) 
                        return false;
                
                    for(int i=0; i<s1.length(); i++)
                        char c1 = s1.charAt(i), c2 = s2.charAt(i);
                        if(c1!=wildcard && c2!=wildcard && c1!=c2)
                            return false;
                
                    return true;
                

                【讨论】:

                • 可能是因为构建通用的东西是编写代码的最佳方式。使用正则表达式,我们有很大的写作能力,但我们会产生(一点)缺乏阅读能力。但是我们仍然可能必须创建多个表达式来处理不同的情况。使用模糊逻辑非常通用,可以处理所有情况。使用直接算法将只处理一种特定的特定情况。
                【解决方案9】:

                如果您正在寻找一种不同的方式来表达通配符,这里有一个选项:

                    String em1 = "52494646";
                    String em2 = "52400646";
                
                    if (em2.startsWith("524")){
                      output.writeUTF(dir + filenames[i]);
                    }
                

                【讨论】:

                  猜你喜欢
                  • 2013-05-02
                  • 1970-01-01
                  • 2021-06-04
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-10-30
                  • 2014-02-08
                  • 1970-01-01
                  • 2020-02-01
                  相关资源
                  最近更新 更多