Как сделать группу захвата необязательной? - PullRequest
0 голосов
/ 28 мая 2018

Ввод

example("This is tes't")

example('This is the tes\"t')

Выход должен быть

This is tes't

This is the tes"t

Код

 String text = "example(\"This is tes't\")";
//String text = "$.i18nMessage('This is the tes\"t\')";
final String quoteRegex = "example.*?(\".*?\")?('.*?')?";
        Matcher matcher0 = Pattern.compile(quoteRegex).matcher(text);
        while (matcher0.find()) {
            System.out.println(matcher0.group(1));
            System.out.println(matcher0.group(2));

        }

Я вижу вывод как

null
null

Хотя, когда я использую регулярное выражение example.*?(\".*?\"), он возвращает This is tes't, а когда я использую example.*?('.*?') он возвращает This is the tes"t, но когда я комбинирую оба с example.*?(\".*?\")?('.*?')?, он возвращает ноль.Почему?

1 Ответ

0 голосов
/ 28 мая 2018

Последовательность подшаблона .*?(\".*?\")?('.*?')? в конце вашего регулярного выражения может соответствовать пустой строке (все 3 части количественно определены с * / *?, которые соответствуют 0 или более символам).После сопоставления example, .*? сначала пропускается и расширяется только тогда, когда последующие подшаблоны не совпадают.Тем не менее, они оба соответствуют пустой строке до (, поэтому у вас есть example в matcher0.group(0).

Используйте любое чередование, которое делает группу 1 обязательной ( demo ):

Pattern.compile("example.*?(\".*?\"|'.*?')"

Или вариант с закаленным жадным жетоном ( demo ), который позволяет избавиться от чередования:

Pattern.compile("example.*?(([\"'])(?:(?!\\2).)*\\2)"

Или, лучше, поддержкаэкранированные последовательности ( еще одна демонстрация ):

Pattern.compile("example.*?(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"|'[^'\\\\]*(?:\\\\.[^'\\\\]*)*')"

Во всех трех примерах вам нужен только доступ к группе 1. Если между example и * 1028 может быть только (* или ', вы должны заменить .*? на \(, так как это сделает сопоставление более безопасным.Хотя использование регулярного выражения для сопоставления строковых литералов никогда не бывает слишком безопасным (по крайней мере, с одним регулярным выражением).

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