2017-01-11 3 views
2

Я изучаю .NET Regular Expression. Как известно, существует двусмысленность между восьмеричными escape-кодами (например, \ 16) и \ числом обратных ссылок. https://msdn.microsoft.com/en-us/library/thwdfzxy.aspxЧто соответствует .NET Regex " 19abc"?

Мой вопрос: Что делает регулярные выражения, как \19 или \288 матча, когда группа с этим номером не определен в шаблоне регулярного выражения?

Ни он, ни действительный номер группы, ни действительный восьмеричный код. Но это правильное регулярное выражение (даже \14848486 действителен) - конструктор Regex не генерирует исключение ArgumentException, но я не смог найти строку ввода, соответствующую такой escape-последовательности.

Мне просто интересно, как интерпретировать только выражение.

+0

'\ 14848486' соответствует восьмеричному 14, а затем последовательность' 848486' –

+0

Извините. Я имел в виду '\ 18848486' (когда второе число равно 8 или 9). – rittergig

ответ

2

Неоднозначность возникает, когда существует несколько возможностей для анализа шаблона. Скажем, в шаблоне (.)(.)(.)(.)(.)(.)(.)(.)(.)(.)\10 с 10 захватывающими группами мы можем говорить о двусмысленности, так как 1 и 10 могут ссылаться на существующую группу, но механизм .NET regex устраняет эту двусмысленность с наибольшим возможным значением, а это регулярное выражение won't match 12345678901, but will match 12345678900. Чтобы избавиться от двусмысленности, вам необходимо использовать \k<ID> обратные ссылки. (.)(.)(.)(.)(.)(.)(.)(.)(.)(.)\k<1>0 будет соответствовать 123456789010, но не 123456789000.

Образец \14848486 соответствует восьмеричному символу 14, а затем последовательности 848486, поскольку здесь нет двусмысленности.

Образец \18848486 будет соответствовать восьмеричному символу, а затем последовательность символов 8848486. См this C# demo:

var s = Regex.Match("\u00018848486", @"\18848486"); 
if (s.Success) Console.WriteLine(s.Value); // => 8848486 

Я также предлагаю использовать Ultrapico Expresso (не принадлежность) для отладки .NET регулярных выражений см скриншот:

enter image description here

Что касается \19 и \288:

enter image description here

Кроме того, когда вы используете задний ремень к отсутствующей группе, как в \k<1>8848486, вы will get a System.ArgumentException: parsing '\k<1>8848486' - Reference to undefined group number N exception. Когда у вас есть 8 или 9 после \, как в \8848486, вы получите System.ArgumentException: parsing '\8848486' - Unrecognized escape sequence N exception.

+0

«Шаблон \ 18848486 будет соответствовать восьмеричному символу 1, а затем последовательность символов 8848486». Вы уверены? Что касается восьмеричного представления MSDN, нужны две или древовидные цифры, а не одна. Но спасибо. однако, я попробую. – rittergig

+0

Да, я уверен. Механизм регулярных выражений .NET позволяет использовать короткие короткие восьмизначные обозначения. Есть 2 случая, когда после обратного слэша есть '8' или' 9', тогда возникает исключение синтаксического анализа. –

+0

Да, вы правы. Я просто проверил его в интерактивном окне Visual Studio C# - и результаты те же: > System.Text.RegularExpressions.Regex.IsMatch (((char) 1) .ToString() + "9", @ "^ \ 01 [9] "); // true > System.Text.RegularExpressions.Regex.IsMatch (((char) 1) .ToString() + "9", @ "^ \ 19"); // true – rittergig

0

Wiktor Stribiżew является правильным.

Вот мое резюме для по умолчанию (канонического) поведения .NET Regex двигатель

  • Выражение \1 через \9 (без дальнейшего следующей цифры) всегда интерпретируются как обратные ссылки, а не как восьмеричные коды.(https://msdn.microsoft.com/en-us/library/thwdfzxy.aspx)
  • Использование \1 через \9 приведет к исключению ArgumentException, если в шаблоне регулярного выражения не определена группа захвата этого указанного числа. (parsing '\8' - Reference to undefined group number)
  • Если это многоточечное выражение, механизм Regex сначала пытается сопоставить последовательность десятичных цифр (после \) в качестве обратной ссылки на эту пронумерованную группу (группу захвата).
  • Если группа захвата с этим номером в шаблоне регулярного выражения не определена, тогда двигатель пытается интерпретировать последовательность цифр в виде восьмеричного кода:
  • Если есть 3 или более восьмеричные цифры (0 ... 7) в последовательности, то двигатель соответствует символу кода с первыми тремя цифрами. Любая другая следующая цифра будет соответствовать как литерал.
    • Пример: \040 → соответствует octal 040
    • Пример: \0040 → соответствует octal 004, то 0
    • Пример: \134 → соответствует octal 134
    • Пример: \134567 → соответствует octal 134, то 5, то 6, то 7
  • Иначе, если есть 2 восьмеричные цифры (0 ... 7), то двигатель соответствует символу кода с этими двумя цифрами. Любая другая следующая цифра будет соответствовать как литерал.
    • Пример: \049 → соответствует octal 04, то 9
    • Пример: \13 → соответствует octal 13
    • Пример: \138567 → соответствует octal 13, то 8, то 5, то 6, то 7
  • Иначе, если есть только 1 восьмеричная цифра (0 ... 7), то двигатель соответствует символу кода wi th это 1 цифра. Любая другая следующая цифра будет соответствовать как литерал.
    • Пример: \0 → соответствует octal 0
    • Пример: \08 → соответствует octal 0, то 8
    • Пример: \7 → соответствует octal 7
    • Пример: \19456 → соответствует octal 1, то 9, то 4, то 5 , затем 6
  • Иначе, если после обратной косой черты будут нулевые восьмеричные цифры, тогда двигатель выкинет исключение ArgumentException.
    • Пример: \81 → броски ArgumentException: parsing '\81' - Unrecognized escape sequence \8
    • Пример: \975 → броски ArgumentException: parsing '\975' - Unrecognized escape sequence \9

Но ПРИМЕЧАНИЕ: поведения отличается, если вы используете RegexOption ECMAScript. https://msdn.microsoft.com/en-us/library/yd1hzczs.aspx#ECMAScript