Регулярное выражение для соответствия одной буквы от А до Я - PullRequest
0 голосов
/ 17 сентября 2018

Я хочу, чтобы регулярное выражение совпадало с одной буквой в строке (от A до Z по порядку):

Он должен найти букву «А», если нет «А», он должен найти букву «В», затем «С» и так далее ...

Примеры ->

  • BCD A E

  • C B DE -> Так как здесь нет 'A, оно совпадает с B

  • Y X Z

  • B A AC -> Так как есть два "А", он находит самый левый первый символ.


Дополнительная информация:

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

С учетом строчной буквы удалите k символов из этой строки. Первый удалить все буквы «а», затем букву «б», затем «с» и т. д.

. Это было мое решение:

public static String remove(String s, int k) {
  for (int c : s.chars().sorted().limit(k).toArray())
    s = s.replaceFirst(Character.toString((char) c), "");
  return s;
}

Но я бы хотел попробовать это с регулярным выражением вроде:

public static String remove(String s, int k) {
  while (k-- > 0)
    s = s.replaceFirst(MY_MAGIC_REGEX_STR, "");
  return s;
}

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Следующее регулярное выражение работает по желанию:

(?i)A|B(?!.*[A-A])|C(?!.*[A-B])|D(?!.*[A-C])|E(?!.*[A-D])|F(?!.*[A-E])|G(?!.*[A-F])|H(?!.*[A-G])|I(?!.*[A-H])|J(?!.*[A-I])|K(?!.*[A-J])|L(?!.*[A-K])|M(?!.*[A-L])|N(?!.*[A-M])|O(?!.*[A-N])|P(?!.*[A-O])|Q(?!.*[A-P])|R(?!.*[A-Q])|S(?!.*[A-R])|T(?!.*[A-S])|U(?!.*[A-T])|V(?!.*[A-U])|W(?!.*[A-V])|X(?!.*[A-W])|Y(?!.*[A-X])|Z(?!.*[A-Y])

Регулярное выражение состоит из 26 терминов (один термин на букву), которые объединяются через оператор чередования (|). A (?! B) - это оператор отрицательного просмотра, который соответствует A, если за A не следует B. За (? I) просто запускается нечувствительность к регистру.

В целом регулярное выражение находит сначала все буквы А слева направо, затем все буквы слева направо и т. Д.

Из-за длины регулярного выражения его удобнее создавать программно:

// Generate regEx
String regEx = "(?i)" + "A" + "|";  
for (char i = 'B'; i <= 'Z'; i++ ) {
    regEx += i + "(?!.*[A-" + (char)(i-1) + "])" + "|";
}
regEx = regEx.substring(0, regEx.length() - 1);
System.out.println(regEx);

Для следующего примера:

String example = "AAAZZZHHAAAZZHHHAAZZZHH"; 

// Output
while(example.length() != 0) {
    System.out.println(example);
    example = example.replaceFirst(regEx, "");
}

вывод:

AAAZZZHHAAAZZHHHAAZZZHH
AAZZZHHAAAZZHHHAAZZZHH
AZZZHHAAAZZHHHAAZZZHH
ZZZHHAAAZZHHHAAZZZHH
ZZZHHAAZZHHHAAZZZHH
ZZZHHAZZHHHAAZZZHH
ZZZHHZZHHHAAZZZHH
ZZZHHZZHHHAZZZHH
ZZZHHZZHHHZZZHH
ZZZHZZHHHZZZHH
ZZZZZHHHZZZHH
ZZZZZHHZZZHH
ZZZZZHZZZHH
ZZZZZZZZHH
ZZZZZZZZH
ZZZZZZZZ
ZZZZZZZ
ZZZZZZ
ZZZZZ
ZZZZ
ZZZ
ZZ
Z
0 голосов
/ 17 сентября 2018

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

public char findLowestChar(String input) {
    char[] array = input.toCharArray();
    char chr = 'Z';     // works so long as input is non-empty
    for (int i=0; i < array.length; ++i) {
        if (array[i] < chr) {
            chr = array[i];
        }
    }
    return chr;
}

Я предполагаю, что во входной строке всегда будет хотя бы одна буква A-Z. Если нет, и вы также хотели реализовать это внутри метода, то вам также следует обработать пустой регистр ввода.

Edit:

Вы просто существенно изменили свой вопрос. Но оказывается, что приведенный выше код все еще может быть частью обновленного ответа. Теперь вы можете выполнять итерацию k раз и на каждом шаге запускать приведенный выше код, чтобы найти самую нижнюю букву. Затем выполните String#replaceAll, чтобы удалить все вхождения этой буквы.

String input = "BCDAE";
// remove k=4 characters, starting with (maybe) A, from the input string
for (int k=0; k < 4 && input.length() > 0; ++k) {
    char lowest = findLowestChar(input);
    input = input.replaceAll(String.valueOf(lowest), "");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...