Вопрос в том, может ли .
шаблон соответствовать любому символу? Ответ варьируется от двигателя к двигателю. Основное различие заключается в том, используется ли шаблон библиотекой регулярных выражений POSIX или не-POSIX.
Специальное примечание о шаблонах lua : они не считаются регулярными выражениями, но .
соответствует любому символу там, как и движки на основе POSIX.
Другое примечание по matlab и октава : .
соответствует любому символу по умолчанию ( demo ): str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match');
(tokens
содержит a abcde\n fghij
пункт).
Кроме того, во всех boost regex грамматика точка соответствует разрывам строки по умолчанию. Boost в ECMAScript грамматике позволяет отключить это с regex_constants::no_mod_m
( source ).
Что касается oracle (на основе POSIX), используйте n
option ( demo ): select regexp_substr('abcde' || chr(10) ||' fghij<Foobar>', '(.*)<Foobar>', 1, 1, 'n', 1) as results from dual
Двигатели на базе POSIX :
Простое .
уже соответствует разрывам строк, нет необходимости использовать какие-либо модификаторы, см. bash ( demo ).
tcl ( демо ), postgresql ( демо ), r (TRE, база R движок по умолчанию без perl=TRUE
, для базы R с perl=TRUE
или для stringr / stringi паттернов, используйте встроенный модификатор (?s)
) ( demo ) также относитесь к .
таким же образом.
Однако , большинство инструментов на основе POSIX обрабатывают ввод построчно. Следовательно, .
не соответствует разрывам строк только потому, что они не находятся в области видимости. Вот несколько примеров, как это переопределить:
- sed - Есть несколько обходных путей, самый точный, но не очень безопасный -
sed 'H;1h;$!d;x; s/\(.*\)><Foobar>/\1/'
(H;1h;$!d;x;
выкладывает файл в память). Если целые строки должны быть включены, можно рассмотреть sed '/start_pattern/,/end_pattern/d' file
(удаление из начала закончится с включенными совпадающими линиями) или sed '/start_pattern/,/end_pattern/{{//!d;};}' file
(с исключением совпадающих строк).
- perl -
perl -0pe 's/(.*)<FooBar>/$1/gs' <<< "$str"
(-0
выгружает весь файл в память, -p
печатает файл после применения сценария, заданного -e
). Обратите внимание, что использование -000pe
приведет к удалению файла и активации «режима абзаца», когда Perl использует последовательные переводы строки (\n\n
) в качестве разделителя записей.
- GNU-grep -
grep -Poz '(?si)abc\K.*?(?=<Foobar>)' file
. Здесь z
разрешает разброс файла, (?s)
включает режим DOTALL для шаблона .
, (?i)
включает режим без учета регистра, \K
опускает сопоставленный текст, *?
- это ленивый квантификатор, (?=<Foobar>)
соответствует местоположению до <Foobar>
.
- pcregrep -
pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file
(M
здесь разрешает выпадение файла). Примечание pcregrep
- хорошее решение для пользователей Mac OS grep
.
См. Демонстрации .
Двигатели без POSIX :
- php - Использовать
s
модификатор PCRE_DOTALL модификатор : preg_match('~(.*)<Foobar>~s', $s, $m)
( demo )
- c # - Использовать флаг
RegexOptions.Singleline
( демо ):
- var result = Regex.Match(s, @"(.*)<Foobar>", RegexOptions.Singleline).Groups[1].Value;
- var result = Regex.Match(s, @"(?s)(.*)<Foobar>").Groups[1].Value;
- powershell - Использовать
(?s)
встроенный параметр: $s = "abcde`nfghij<FooBar>"; $s -match "(?s)(.*)<Foobar>"; $matches[1]
- perl - Использовать модификатор
s
(или (?s)
встроенная версия в начале) ( demo ): /(.*)<FooBar>/s
- python - использовать
re.DOTALL
(или re.S
) флаги или (?s)
встроенный модификатор ( demo ): m = re.search(r"(.*)<FooBar>", s, flags=re.S)
(а затем if m:
, print(m.group(1))
)
- java - Использовать модификатор
Pattern.DOTALL
(или встроенный флаг (?s)
) ( demo ): Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)
- groovy - Использовать
(?s)
модификатор in-pattern ( demo ): regex = /(?s)(.*)<FooBar>/
- scala - Использовать модификатор
(?s)
( demo ): "(?s)(.*)<Foobar>".r.findAllIn("abcde\n fghij<Foobar>").matchData foreach { m => println(m.group(1)) }
- javascript - Используйте
[^]
или обходные пути [\d\D]
/ [\w\W]
/ [\s\S]
( демо ): s.match(/([\s\S]*)<FooBar>/)[1]
- c ++ (
std::regex
) Используйте [\s\S]
или обходные пути JS ( demo ): regex rex(R"(([\s\S]*)<FooBar>)");
- vba - использовать тот же подход, что и в JavaScript,
([\s\S]*)<Foobar>
.
- ruby - Использовать
/m
MULTILINE модификатор ( демо ): s[/(.*)<Foobar>/m, 1]
- go - Использовать встроенный модификатор
(?s)
в начале ( demo ): re: = regexp.MustCompile(`(?s)(.*)<FooBar>`)
- swift - Используйте
dotMatchesLineSeparators
или (проще) передать встроенный модификатор (?s)
в шаблон: let rx = "(?s)(.*)<Foobar>"
- target-c - То же, что и Swift,
(?s)
работает проще всего, но вот как можно использовать опцию : NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionDotMatchesLineSeparators error:®exError];
- re2 , google-apps-script - Использовать модификатор
(?s)
( demo ): "(?s)(.*)<Foobar>"
(в таблицах Google, =REGEXEXTRACT(A2,"(?s)(.*)<Foobar>")
)
ЗАМЕЧАНИЯ ПО (?s)
:
В большинстве не-POSIX движков можно использовать встроенный модификатор (?s)
(или опцию встроенного флага) для принудительного применения .
для соответствия разрывам строк.
При размещении в начале шаблона (?s)
изменяет поведение всех .
в шаблоне. Если (?s)
находится где-то после начала, будут затронуты только те .
, которые расположены справа от него , если это шаблон, переданный в Python re
. В Python re
, независимо от местоположения (?s)
, затрагивается весь шаблон .
. Эффект (?s)
останавливается с помощью (?-s)
. Модифицированная группа может использоваться, чтобы влиять только на указанный диапазон шаблона регулярного выражения (например, Delim1(?s:.*?)\nDelim2.*
сделает первый .*?
совпадением по новым строкам, а второй .*
будет соответствовать только остальной части строки).
POSIX note :
В двигателях без регулярных выражений для сопоставления с любым символом можно использовать конструкции [\s\S]
/ [\d\D]
/ [\w\W]
.
В POSIX [\s\S]
не соответствует ни одному символу (как в JavaScript или любом не-POSIX-механизме), потому что escape-последовательности регулярного выражения не поддерживаются в выражениях в скобках. [\s\S]
анализируется как скобочные выражения, соответствующие одному символу, \
или s
или S
.