Например, это регулярное выражение
(.*)<FooBar>
будет соответствовать:
abcde<FooBar>
Но как мне его сопоставить по нескольким строкам?
abcde
fghij<FooBar>
Например, это регулярное выражение
(.*)<FooBar>
будет соответствовать:
abcde<FooBar>
Но как мне его сопоставить по нескольким строкам?
abcde
fghij<FooBar>
Это зависит от языка, но должен быть модификатор, который вы можете добавить к шаблону регулярного выражения. В PHP это:
/(.*)<FooBar>/s
s в конце заставляет точку соответствовать всем символам, включая символы новой строки.
Попробуйте следующее:
((.|\n)*)<FooBar>
В основном он говорит "любой символ или символ новой строки" повторяется ноль или более раз.
Если вы используете поиск Eclipse, вы можете включить опцию "DOTALL", чтобы сделать ".". сопоставить любой символ, включая разделители строк: просто добавьте "(? s)" в начале строки поиска. Пример:
(?s).*<FooBar>
Вопрос в том, может ли шаблон .
соответствовать любому символу? Ответ варьируется от двигателя к двигателю. Основное различие заключается в том, используется ли шаблон библиотекой регулярных выражений POSIX или не-POSIX.
Особое примечание о lua-patterns: они не считаются регулярными выражениями, но .
соответствует любому символу там, так же как и движки на основе POSIX.
Еще одно примечание к matlab и octave: .
соответствует любому символу по умолчанию (demo): str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match');
(tokens
содержит элемент abcde\n fghij
).
Кроме того, во всех грамматиках регулярных выражений boost точка соответствует разрывам строк по умолчанию. Повышение грамматики ECMAScript позволяет отключить это с помощью regex_constants::no_mod_m
(источник).
Что касается oracle (на основе POSIX), используйте параметр n
(demo): select regexp_substr('abcde' || chr(10) ||' fghij<Foobar>', '(.*)<Foobar>', 1, 1, 'n', 1) as results from dual
Движки на основе POSIX:
Простой .
уже соответствует разрывам строк, нет необходимости использовать какие-либо модификаторы, см. bash (demo).
tcl (demo), postgresql (demo), r (TRE, базовый движок R по умолчанию без perl=TRUE
, для базы R с perl=TRUE
или для шаблонов stringr/stringi используйте встроенный модификатор (?s)
(demo), а также обрабатывайте .
таким же образом.
Однако большинство инструментов на основе POSIX обрабатывают ввод построчно. Следовательно, .
не соответствует разрывам строк только потому, что они не находятся в области видимости. Вот несколько примеров, как это переопределить:
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 -0pe 's/(.*)<FooBar>/$1/gs' <<< "$str"
(-0
выкладывает весь файл в память, -p
печатает файл после применения сценария, заданного -e
). Обратите внимание, что использование -000pe
приведет к удалению файла и активированию "режима абзаца", в котором Perl использует последовательные переводы строки (\n\n
) в качестве разделителя записей.grep -Poz '(?si)abc\K.*?(?=<Foobar>)' file
. Здесь z
включает слежку за файлом, (?s)
включает режим DOTALL для шаблона .
, (?i)
включает режим без учета регистра, \K
опускает сопоставленный текст, пока что, *?
является ленивым квантификатором, (?=<Foobar>)
соответствует местоположению до <Foobar>
.pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file
(здесь M
разрешает выпадение файла). Примечание. pcregrep
- хорошее решение для пользователей Mac OS grep
.Движки не на основе POSIX:
s
PCRE_DOTALL модификатор: preg_match('~(.*)<Foobar>~s', $s, $m)
(демо)RegexOptions.Singleline
(demo): var result = Regex.Match(s, @"(.*)<Foobar>", RegexOptions.Singleline).Groups[1].Value;
var result = Regex.Match(s, @"(?s)(.*)<Foobar>").Groups[1].Value;
(?s)
: $s = "abcde'nfghij<FooBar>"; $s -match "(?s)(.*)<Foobar>"; $matches[1]
s
(или встроенную версию (?s)
в начале) (demo): /(.*)<FooBar>/s
re.DOTALL
(или re.S
) или встроенный модификатор (?s)
(demo): m = re.search(r"(.*)<FooBar>", s, flags=re.S)
(а затем if m:
, print(m.group(1))
)Pattern.DOTALL
(или встроенный флаг (?s)
) (demo): Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)
(?s)
(demo): regex = /(?s)(.*)<FooBar>/
(?s)
(demo): "(?s)(.*)<Foobar>".r.findAllIn("abcde\n fghij<Foobar>").matchData foreach { m => println(m.group(1)) }
[^]
или обходные пути [\d\D]
/[\w\W]
/[\s\S]
(demo): s.match(/([\s\S]*)<FooBar>/)[1]
std::regex
) Используйте [\s\S]
или обходные пути JS (demo): regex rex(R"(([\s\S]*)<FooBar>)");
([\s\S]*)<Foobar>
./m
модификатор MULTILINE (демо): s[/(.*)<Foobar>/m, 1]
(?s)
в начале (демонстрация): re: = regexp.MustCompile('(?s)(.*)<FooBar>')
dotMatchesLineSeparators
или (проще) передайте встроенный модификатор (?s)
в шаблон: let rx = "(?s)(.*)<Foobar>"
(?s)
работает проще всего, но вот как можно использовать опцию option can be used: NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionDotMatchesLineSeparators error:®exError];
(?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 примечание:
В двигателях регулярных выражений, отличных от POSIX, для соответствия любому символу могут использоваться конструкции [\s\S]
/[\d\D]
/[\w\W]
.
В POSIX [\s\S]
не соответствует ни одному символу (как в JavaScript или любом не-POSIX-движке), потому что escape-последовательности регулярного выражения не поддерживаются в выражениях в скобках. [\s\S]
анализируется как выражения в скобках, которые соответствуют одному символу, \
или s
или S
.
В JavaScript используйте /[\S\s]*<Foobar>/
. Источник
([\s\S]*)<FooBar>
Точка соответствует всем, кроме строк новой строки (\ r\n). Поэтому используйте \s\S, который будет соответствовать всем символам.
В Ruby ruby вы можете использовать опцию 'm
' (многострочный):
/YOUR_REGEXP/m
Для получения дополнительной информации см. документацию Regexp на ruby-doc.org.
мы также можем использовать
(.*?\n)*?
чтобы соответствовать всем, включая новую линию без жадных
Это сделает новую строку опциональной
(.*?|\n)*?
"."
обычно не соответствует разрыву строки. Большинство механизмов регулярных выражений позволяют вам добавить S
-flag (также называемый DOTALL
и SINGLELINE
), чтобы сделать "."
также совпадающим с новыми.
Если это не удается, вы можете сделать что-то вроде [\S\s]
.
Для Eclipse работало следующее выражение:
Foo
jadajada Bar "
Регулярное выражение:
Foo[\S\s]{1,10}.*Bar*
/(.*)<FooBar>/s
s вызывает Dot (.) для соответствия возврату каретки
В регулярном выражении, основанном на java, вы можете использовать [\s\S]
Обратите внимание, что (.|\n)*
может быть менее эффективным, чем (например) [\s\S]*
(если языковые регулярные выражения поддерживают такие escape-последовательности), а не поиск того, как указать модификатор, который делает. также соответствуют новостям. Или вы можете пойти с альтернативами POSIXy, например [[:space:][:^space:]]*
.
Используйте RegexOptions.Singleline, он меняет значение. включить новые строки
Regex.Replace(content, searchText, replaceText, RegexOptions.Singleline);
Использовать шаблонный модификатор sU получит желаемое соответствие в PHP.
preg_match('/(.*)/sU',$content,$match);
http://dreamluverz.com/developers-tools/regex-match-all-including-new-line http://php.net/manual/en/reference.pcre.pattern.modifiers.php
В контексте использования в языках регулярные выражения действуют на строки, а не на строки. Поэтому вы должны иметь возможность нормально использовать регулярное выражение, считая, что входная строка имеет несколько строк.
В этом случае заданное регулярное выражение будет соответствовать всей строке, так как "<FooBar> " настоящее. В зависимости от специфики реализации регулярного выражения значение $1 (полученное из "(. *)" ) Будет либо "fghij", либо "abcde\nfghij". Как говорили другие, некоторые реализации позволяют вам контролировать, является ли "." будет соответствовать новой строке, что даст вам выбор.
Использование регулярных выражений на основе строк обычно используется для командной строки, например egrep.
У меня была такая же проблема и она была решена, возможно, не лучшим образом, но она работает. Я заменил все разрывы строк, пока не выполнил свой настоящий матч:
mystring= Regex.Replace(mystring, "\r\n", "")
Я манипулирую HTML, поэтому разрывы строк для меня в этом случае не имеют большого значения.
Я попробовал все вышеперечисленные предложения без везения, я использую .Net 3.5 FYI
В Javascript вы можете использовать [^] * для поиска от нуля до бесконечных символов, включая разрывы строк.
$("#find_and_replace").click(function() {
var text = $("#textarea").val();
search_term = new RegExp("[^]*<Foobar>", "gi");;
replace_term = "Replacement term";
var new_text = text.replace(search_term, replace_term);
$("#textarea").val(new_text);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="find_and_replace">Find and replace</button>
<br>
<textarea ID="textarea">abcde
fghij<Foobar></textarea>
в целом. не соответствует символам новой строки, поэтому попробуйте ((.|\n)*)<foobar>
Я хотел сопоставить конкретный блок if в java
...
...
if(isTrue){
doAction();
}
...
...
}
Если я использую regExp
if \(isTrue(.|\n)*}
он включал замыкающую скобку для блока метода, поэтому я использовал
if \(!isTrue([^}.]|\n)*}
чтобы исключить замыкающую скобку из подстановочного соответствия.
Часто нам приходится изменять подстроку с несколькими ключевыми словами, разбросанными по строкам, предшествующим подстроке. Рассмотрим элемент xml:
<TASK>
<UID>21</UID>
<Name>Architectural design</Name>
<PercentComplete>81</PercentComplete>
</TASK>
Предположим, мы хотим изменить 81, какое-то другое значение, скажем 40. Сначала определите .UID.21..UID.
, затем пропустите все символы, включая \n
до .PercentCompleted.
. Шаблон регулярного выражения и спецификация замены:
String hw = new String("<TASK>\n <UID>21</UID>\n <Name>Architectural design</Name>\n <PercentComplete>81</PercentComplete>\n</TASK>");
String pattern = new String ("(<UID>21</UID>)((.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
String replaceSpec = new String ("$1$2$440$6");
//note that the group (<PercentComplete>) is $4 and the group ((.|\n)*?) is $2.
String iw = hw.replaceFirst(pattern, replaceSpec);
System.out.println(iw);
<TASK>
<UID>21</UID>
<Name>Architectural design</Name>
<PercentComplete>40</PercentComplete>
</TASK>
Подгруппа (.|\n)
, вероятно, является отсутствующей группой $3
. Если мы сделаем это не захватывающим на (?:.|\n)
, то $3
будет (<PercentComplete>)
. Таким образом, шаблон и replaceSpec
также могут быть:
pattern = new String("(<UID>21</UID>)((?:.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
replaceSpec = new String("$1$2$340$5")
и замена работает правильно, как и раньше.
Обычно при поиске трех последовательных строк в Powershell это выглядит так:
$file = get-content file.txt -raw
$pattern = 'lineone\r\nlinetwo\r\nlinethree\r\n' # "windows" text
$pattern = 'lineone\nlinetwo\nlinethree\n' # "unix" text
$pattern = 'lineone\r?\nlinetwo\r?\nlinethree\r?\n' # both
$file -match $pattern
# output
True
Как ни странно, это будет текст UNIX в приглашении, но текст Windows в файле:
$pattern = 'lineone
linetwo
linethree
'
Вот способ распечатать окончания строк:
'lineone
linetwo
linethree
' -replace "'r",'\r' -replace "'n",'\n'
# output
lineone\nlinetwo\nlinethree\n
Один из способов - использовать флаг s
(как и принятый ответ):
/(.*)<FooBar>/s
Второй способ - использовать флаг m
(многострочный) и любой из следующих шаблонов:
/([\s\S]*)<FooBar>/m
или
/([\d\D]*)<FooBar>/m
или
/([\w\W]*)<FooBar>/m
jex.im визуализирует регулярные выражения: