Поддержка поддержки lookbehind
Основные разновидности regex имеют различные поддержки для lookbehind по-разному;некоторые налагают определенные ограничения, а некоторые даже не поддерживают его вообще.
- Javascript: не поддерживается
- Python: только фиксированная длина
- Java: конечная длинатолько
- .NET: без ограничений
Ссылки
Python
В Python, где поддерживается только задний просмотр фиксированной длины, ваш оригинальный шаблон вызывает ошибку, поскольку \d{1,2}
явно не имеет фиксированной длины.Вы можете «исправить» это, чередуя два разных вида сзади фиксированной длины, например, что-то вроде этого:
(?<=^\d\/)\d{1,2}|(?<=^\d\d\/)\d{1,2}
Или, возможно, вы можете поместить оба вида взгляда как альтернативы не захватывающей группы:
(?:(?<=^\d\/)|(?<=^\d\d\/))\d{1,2}
(обратите внимание, что вы можете просто использовать \d
без скобок).
Тем не менее, вероятно, вместо этого гораздо проще использовать группу захвата:
^\d{1,2}\/(\d{1,2})
Примечаниечто findall
возвращает то, что захватывает группа 1, если у вас есть только одна группа.Группа захвата поддерживается более широко, чем внешний вид, и часто приводит к более читаемому шаблону (например, в этом случае).
Этот фрагмент иллюстрирует все вышеперечисленные пункты:
p = re.compile(r'(?:(?<=^\d\/)|(?<=^\d\d\/))\d{1,2}')
print(p.findall("12/34/56")) # "[34]"
print(p.findall("1/23/45")) # "[23]"
p = re.compile(r'^\d{1,2}\/(\d{1,2})')
print(p.findall("12/34/56")) # "[34]"
print(p.findall("1/23/45")) # "[23]"
p = re.compile(r'(?<=^\d{1,2}\/)\d{1,2}')
# raise error("look-behind requires fixed-width pattern")
Ссылки
Java
Java поддерживает только просмотр конечной длины, поэтому вы можете использовать \d{1,2}
, как в исходном шаблоне.Это демонстрируется следующим фрагментом:
String text =
"12/34/56 date\n" +
"1/23/45 another date\n";
Pattern p = Pattern.compile("(?m)(?<=^\\d{1,2}/)\\d{1,2}");
Matcher m = p.matcher(text);
while (m.find()) {
System.out.println(m.group());
} // "34", "23"
Обратите внимание, что (?m)
является встроенным Pattern.MULTILINE
, так что ^
соответствует началу каждой строки.Также обратите внимание, что, поскольку \
является escape-символом для строковых литералов, вы должны написать "\\"
, чтобы получить одну обратную косую черту в Java.
C-Sharp
C # поддерживает полное регулярное выражениена взгляд позади.В следующем фрагменте показано, как можно использовать +
повторение для внешнего вида:
var text = @"
1/23/45
12/34/56
123/45/67
1234/56/78
";
Regex r = new Regex(@"(?m)(?<=^\d+/)\d{1,2}");
foreach (Match m in r.Matches(text)) {
Console.WriteLine(m);
} // "23", "34", "45", "56"
Обратите внимание, что в отличие от Java, в C # вы можете использовать @ - заключенную в кавычки строку , чтобы вы нене нужно бежать \
.
Для полноты, вот как вы можете использовать опцию захвата группы в C #:
Regex r = new Regex(@"(?m)^\d+/(\d{1,2})");
foreach (Match m in r.Matches(text)) {
Console.WriteLine("Matched [" + m + "]; month = " + m.Groups[1]);
}
Учитывая предыдущий text
, это печатает:
Matched [1/23]; month = 23
Matched [12/34]; month = 34
Matched [123/45]; month = 45
Matched [1234/56]; month = 56
Смежные вопросы