2012-07-02 7 views
3

Я не люблю образец Regex, работающий на Java, чтобы удалить все дублированные символы.Как удалить все дублированные символы

Этот код не работает: «g» и «<» удалены, более двух символов явно не сведены к одному, а «454» сокращен до «5».

s = "aa hgjii2222 22 FFonn;;;,,1111111111 22< 454"; 
p = Pattern.compile("(.)(.)"); 
m = p.matcher(s); 
System.out.println(m.replaceAll("$1")); 

Выход:

hji222 Fon;, 11111 2 5

Я пробовал другие решения с меньшим успехом.

+0

Каков ожидаемый результат? – kennytm

+0

Не все проблемы должны решаться с помощью регулярных выражений. Почему бы вам просто не перебирать символы и добавлять только текущий символ, если он отличается от предыдущего? –

+1

нет оскорбительных, просто хочу lol в шаблоне '(.) (.)'. во всяком случае, этот шаблон сжимает каждую пару двух символов до первого символа. –

ответ

5

Вы можете сделать:

String s= "aa hgjii2222 22 FFonn;;;,,1111111111 22< 454"; 
s = s.replaceAll("(.)\\1+","$1"); 

Регулярное выражение используется: (.)\\1+

(.) - Matches any non-newline character and remembers it 
\\1+ - One or more repetitions of the remembered character 
+0

Спасибо за объяснение - он отлично работает. –

2

Использование

"(.)\\1+" 

вместо этого.

Первый символ повторяется один или несколько раз.

0

Этот рисунок не работает, что вы надеетесь вообще.

Он находит любого символ, а затем любого характера (не обязательно совпадают с первым), а затем заменяет эту строку два символа с первым матчем (первый символом).

Другими словами, он удаляет все остальные символы.

Я не думаю, что регулярное выражение является правильным инструментом для работы, которую вы ищете; подумайте о том, как это можно реализовать как FSA, и должно быть ясно, что обычные языки вообще не описывают проблему.

Было бы намного проще и, возможно, яснее, просто сделать это в коде. Сохраните набор всех персонажей, с которыми вы столкнулись до сих пор, и удалите любые символы, которые совпадают по мере повтора - что-то вроде:

final Set<Character> charsSeen = new HashSet<Character>(); 
final StringBuilder out = new StringBuilder(); 
for (char c : s.toCharArray()) { 
    if (!charsSeen.contains(c)) { 
     out.append(c); 
     charsSeen.add(c); 
    } 
} 
return out.toString(); 
+1

Спасибо за эту точку зрения. Regex "(.) \\ 1+" - это именно тот инструмент, который мне нужен. Для вашей цели вы можете упростить (потому что Set return false, если значение уже вставлено): if (charsSeen.add (c)) {out.append (c);} .. –

Смежные вопросы