Regex, чтобы удалить все пробелы, кроме ключевых слов и между кавычками - PullRequest
4 голосов
/ 09 октября 2019

Я хочу:

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

  2. игнорируем все между кавычками

Iперепробовал много шаблонов. Самое близкое, что я придумал, это довольно близко, но оно все равно удаляет пробел после ключевых слов, которых я стараюсь избегать.

regex:

\s(?!and|or|if)(?=(?:[^"]*"[^"]*")*[^"]*$)

Test String:

            if    (ans(this) >= ans({1,2})  and (cond({3,4})  or ans(this) <= ans({5,6})), 7, 8)  and {111} > {222}  or ans(this) = "hello    my friend and  or  " and(cond({1,2}) $1 123     

Идеальный результат:

 if (ans(this)>=ans({1,2}) and (cond({3,4}) or ans(this)<=ans({5,6})),7,8) and {111}>{222} or ans(this)="hello    my friend and  or  " and(cond({1,2})$1123

Затем я могу использовать str = str.replaceAll в Java для удаления этих пробелов. Я не против сделать несколько шагов, чтобы получить результат, но я не знаком с регулярным выражением, так что вроде бы застрял.

любая помощь будет признательна!

Примечание: я отредактировал результат. Прости за это. Для пробела вокруг ключевых слов: уменьшите до 1, если есть пробелы. Либо оставьте его, либо добавьте 1 пробел, если он равен 0 (я просто не хочу ", или ans" становится "orans", но "and (cond" становится "и (cond)" нормально (уменьшите до 1 пробела до и 1 пробела)после, если существует). Игнорировать все между кавычками.

Ответы [ 2 ]

2 голосов
/ 09 октября 2019

Вы разумно используете группы захвата. Общая идея здесь будет выглядеть следующим образом:

match_this|or_this|or_even_this|(but_capture_this)

С точки зрения регулярного выражения это может быть

(?:(?:\s+(?:and|or|if)\s+)|"[^"]+")|(\s+)

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


См. демонстрацию на regex101.com (*SKIP*)(*FAIL), которая служит той же цели).
1 голос
/ 10 октября 2019

Вы можете использовать

String example = "            if    (ans(this) >= ans({1,2})  and (cond({3,4})  or ans(this) <= ans({5,6})), 7, 8)  and {111} > {222}  or ans(this) = \"hello    my friend and  or  \" and(cond({1,2}) $1 123    ";
String rx = "\\s*\\b(and|or|if)\\b\\s*|(\"[^\"]*\")|(\\s+)";
Matcher m = Pattern.compile(rx).matcher(example);
example = m.replaceAll(r -> r.group(3) != null ? "" : r.group(2) != null ? r.group(2) : " " + r.group(1) + " ").trim();
System.out.println( example );

См. Демонстрационную версию Java .

Шаблон соответствует

  • \s*\b(and|or|if)\b\s* - 0+ пробелы, граница слова, группа 1: and, or, if, граница слова и затем 0+пробелы
  • | - или
  • (\"[^\"]*\") - группа 2: ", любые 0+ символов, кроме ", а затем "
  • | - или
  • (\s+) - Группа 3: пробелы 1+.

Если группа 3 совпадает, они удаляются, если группа 2 совпадает, она возвращается врезультат и, если группа 1 совпадает, она оборачивается пробелами и вставляется обратно. Весь результат .trim() ред.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...