2016-09-28 3 views
-1

Я ищу выражение регулярного выражения, которое будет обнаруживать повторяющиеся символы в строке. И в настоящее время я не нашел решение, которое соответствует всем моим требованиям.Regex для обнаружения повторяющихся символов

Требования довольно просты:

  • обнаружить любой повторение символа в строку;
  • , чтобы иметь возможность установки повторяющегося счета (например. Больше, чем в два раза)

Примеры требуемого обнаружения (символ «A», более чем в 2 раза, верно, если обнаруживает, иначе ложь)

"АБВГДЕЖ" - ложных

"ABCDABCD" - ложных

«абы cd_ab_ab»- истинный (символ 'а' используется в три раза)

"aabbaabb" - истинные (символы 'A' используется в четыре раза)

Поскольку я не профессионал в регулярных выражениях и использования из них - код фрагмента и описание будет оценен!

Спасибо!

+0

Может быть обманом http://stackoverflow.com/questions/7378451/java-regex-match-count. Или http://stackoverflow.com/questions/275944/java-how-do-i-count-the-number-of-occurrences-of-a-char-in-a-string. –

+0

@iDemigod вы могли бы уточнить, что вы подразумеваете под «для того, чтобы настроить повторение счета (например, более двух раз)» - вы говорите, что хотите указать, что он найден * как минимум * 3 раза, например? –

+0

@ AndyTurner, точно! – iDemigod

ответ

5

Я думаю, что

(.).*\1 

будет работать:

  • (.) матч один символ и захватить
  • .* матча любых промежуточных символов
  • \1 матч захваченной группы снова.

(Вы должны были бы составить с DOTALL флагом, или заменить . с [\s\S] или подобными, если строка содержит символы, которые обычно не подбираются .)

и если вы хотите, чтобы потребовать, чтобы оно найдено по крайней мере в 3 раза, просто изменить квантор вторых двух пуль:

(.)(.*\1){2} 

т.д.

Это собирается быть довольно неэффективным, хотя, потому что ему придется выполнять «поиск следующего совпадающего символа» между каждым символом в строке и концом строки, делая ее по меньшей мере квадратичной.

Возможно, вы не используете обычные выражения, например.

char[] cs = str.toCharArray(); 
Arrays.sort(cs); 
int n = numOccurrencesRequired - 1; 
for (int i = n; i < cs.length; ++i) { 
    boolean allSame = true; 
    for (int j = 1; j <= n && allSame; ++j) { 
    allSame = cs[i] == cs[i - j]; 
    } 
    if (allSame) return true; 
} 
return false; 

Этот тип всех одинаковых символов позволяет вам просто передать строку после поиска смежных одинаковых символов.

Обратите внимание, что это не довольно Работает для любого символа: он будет разделять многоугольные кодовые точки. Вы можете адаптировать приведенный выше код для работы с кодовыми точками, а не с символами.

+0

Энди, не могли бы вы добавить документацию, в которой говорится, что строительство законно? – xenteros

+0

В текущем решении здесь не учитывается требование 2-го ОП. –

+0

@xenteros uh, no, кроме [здесь] (https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html) ... но [это законно] (http://ideone.com/uuxbSb). –

0

Да, такое регулярное выражение существует, но только потому, что множество символов конечно.

regex: .*(a.*a|b.*b|c.*c|...|y.*y|z.*z).* 

Это не имеет никакого смысла. Использовать другой подход:

String string = "something"; 
int[] count = new int[256]; 
for (int i = 0; i < string.length; i++) { 
    int temp = int(string.charAt(i)); 
    count[temp]++; 
} 

Теперь у вас есть все символы, и вы можете использовать их по своему усмотрению.

+0

Не нужно явно вводить char в int. –

1

Попробуйте это регулярное выражение: (.)(?:.*\1)

Это в основном соответствует любому символу (.) следует что-либо .* и сам \1. Если вы хотите проверить наличие двух или более повторов, добавьте только {n,}, а n - количество повторов, которые вы хотите проверить.

+0

На самом деле '.' не соответствует * ничего *. По умолчанию он не соответствует символам строк. –

+1

@ WiktorStribiżew это правильно, но вы можете исправить это с соответствующими флагами, если это необходимо. – Thomas

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