Как найти символы, общие для двух строк в Java, используя один replaceAll? - PullRequest
6 голосов
/ 17 ноября 2010

Предположим, у меня есть:

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 ]

4 голосов
/ 19 ноября 2010

Принятый ответ:

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

содержит ошибку !!!

Что если строка t имеет метасимвол регулярного выражения?В этом случае replaceAll терпит неудачу.

См. Эту программу в качестве примера, где строка t содержит ] в ней и ]метасимвол регулярного выражения, обозначающий конец класса символов.Очевидно, что программа не выдает ожидаемый результат.

Почему?

Рассмотрим:

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

Теперь регулярное выражение станет (просто подставим t):

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

То есть заменить любой символ, кроме 4, 5, 9, L, P , за которым следует ], ни с чем.Что явно не то, что вам нужно.

Чтобы исправить это, вам нужно выбрать ] in t.Вы можете сделать это вручную следующим образом:

String t = "459LP\\]";

и регулярное выражение прекрасно работает .

Это распространенная проблема при использовании регулярного выражения, поэтомукласс java.util.regex.Pattern предоставляет статический метод с именем quote , который можно использовать для выполнения именно этого: заключать в кавычки регулярные выражения-метасимволы так, чтобы они обрабатывались буквально.

Таким образом, перед использованием t в replaceAll вы указываете его как:

t = Pattern.quote(t);

Программа, использующая метод кавычек , работает как ожидалось.

4 голосов
/ 17 ноября 2010
String commonChars = s.replaceAll("[^"+t+"]","");

Обратите внимание, что вам может потребоваться экранировать специальные символы в t, например, используя Pattern.quote(t) вместо t выше.

2 голосов
/ 06 сентября 2012

Принят неправильный ответ. Поскольку replaceAll является шаблоном, мы должны рассмотреть синтаксис. Что будет если s1 = "\\t"? А что будет если s1 = "]{"?

Если все символы находятся в диапазоне [0 - 255], мы можем работать так:

  1. byte[] tmp = new byte[255];
  2. цикл каждого символа в первой строке

    for (char c : str1.toCharArray())<br> // 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, индекс это правильный символ, который мы ищем.

Другое решение использует HashSet.retainAll(Collection<?> c);

1 голос
/ 09 мая 2012
public class common {

   public static void main(String args[]) {
      String s = "FIRST";
      String s1 = "SECOND";
      String common = s.replaceAll("[^" + s1 + "]", "");
      System.out.println(common);
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...