如何使用单个replaceAll找到Java中两个字符串的共同字符?

时间:2010-11-17 11:33:02

标签: java regex optimization string

假设我有:

String s = "1479K";
String t = "459LP";

我要返回

String commonChars = "49";

两个字符串之间的共同字符。

显然,可以使用标准循环:

String commonChars = "";
for (i = 0; i < s.length; i++)
{
    char ch = s.charAt(i);
    if (t.indexOf(ch) != -1)
    {
        commonChars = commonChars + ch;
    }
}

但是我希望能够使用replaceAll在一行中完成此操作。这可以按如下方式完成:

String commonChars = s.replaceAll("["+s.replaceAll("["+t+"]","")+"]","");

我的问题是:是否可以使用replaceAll的单一调用来执行此操作?什么是正则表达式?我认为我必须使用某种前瞻性,但是当我想到它时,我的大脑就会变得糊涂。

4 个答案:

答案 0 :(得分:4)

String commonChars = s.replaceAll("[^"+t+"]","");

请注意,您可能需要转义t中的特殊字符,例如使用Pattern.quote(t)代替上面的t

答案 1 :(得分:4)

接受的答案:

String commonChars = s.replaceAll("[^"+t+"]","");

有一个错误!!!

如果字符串t具有正则表达式元字符,该怎么办?在这种情况下,replaceAll失败。

See this program作为示例,其中字符串t中包含]]是一个正则表达式元字符,用于标记字符类的结尾。显然,该程序不会产生预期的输出。

为什么?

考虑:

String s = "1479K";
String t = "459LP]";

现在正则表达式将成为(只替换t):

String commonChars = s.replaceAll("[^459LP]]","");

除了459LP 后跟 {{ {1}}没有任何东西。这显然不是你想要的。

要解决这些问题,您需要转义]中的]。您可以手动执行以下操作:

t

regex works fine

这是使用正则表达式时的常见问题,因此String t = "459LP\\]"; 类提供了一个名为quote的静态方法,可用于执行此操作:引用正则表达式元字符,以便按字面处理它们。

所以在java.util.regex.Pattern中使用t之前,请将其引用为:

replaceAll

Program using quote method按预期工作。

答案 2 :(得分:2)

接受的答案不正确。因为replaceAll是一个模式,我们必须考虑语法。 如果s1 = "\\t"会怎样?如果s1 = "]{"会发生什么?

如果所有字符都在[0 - 255]范围内,我们可以像这样工作:

  1. byte[] tmp = new byte[255];
  2. 循环第一个字符串中的每个字符

    for (char c : str1.toCharArray())
    // or use charAt(i) here if (tmp[c] == 0) tmp[c] = 1;

  3. 循环第二个字符串中的每个字符

    for (char c : str2.toCharArray()) if (tmp[c] == 1) tmp[c] = 2;

  4. 循环tmp数组,找到值为2的成员,即索引 是我们正在寻找的正确的焦点。

  5. 另一种解决方案是使用HashSet.retainAll(Collection<?> c);

答案 3 :(得分:1)

public class common {

   public static void main(String args[]) {
      String s = "FIRST";
      String s1 = "SECOND";
      String common = s.replaceAll("[^" + s1 + "]", "");
      System.out.println(common);
   }
}