Например, это регулярное выражение
(.*)<FooBar>
будет соответствовать:
abcde<FooBar>
Но как мне сделать так, чтобы он совпадал по нескольким строкам?
abcde
fghij<FooBar>
Например, это регулярное выражение
(.*)<FooBar>
будет соответствовать:
abcde<FooBar>
Но как мне сделать так, чтобы он совпадал по нескольким строкам?
abcde
fghij<FooBar>
Ответы:
Это зависит от языка, но должен быть модификатор, который вы можете добавить к шаблону регулярных выражений. В PHP это:
/(.*)<FooBar>/s
Символ s в конце заставляет точку совпадать со всеми символами, включая символы новой строки.
s
модификатор. Вместо этого делайте [^]*
для того же эффекта.
m
модификатор
Попробуй это:
((.|\n)*)<FooBar>
Это в основном говорит, что «любой символ или перевод строки» повторяется ноль или более раз.
((.|\n|\r)*)<FooBar>
[\s\S]*
или (?s).*
.
Вопрос в том, может ли .
шаблон соответствовать любому персонажу? Ответ варьируется от двигателя к двигателю. Основное различие заключается в том, используется ли шаблон библиотекой регулярных выражений POSIX или не-POSIX.
Специальное примечание о Lua-модель: они не считаются регулярными выражениями, но .
соответствуют любому символу там, так же как и движки на основе POSIX.
Еще одна заметка о MATLAB а также октава: .
соответствует любому символу по умолчанию ( демо ): str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match');
( tokens
содержит abcde\n fghij
элемент).
Кроме того, во всех увеличениеПо умолчанию в регулярных выражениях точка соответствует разрывам строк. Boost's ECMAScript грамматика позволяет отключить это с помощью regex_constants::no_mod_m
( источник ).
Что касается оракул(это основано на POSIX), используйте n
опцию ( демо ):select regexp_substr('abcde' || chr(10) ||' fghij<Foobar>', '(.*)<Foobar>', 1, 1, 'n', 1) as results from dual
Двигатели на базе POSIX :
Простое .
уже соответствует разрывам строк, нет необходимости использовать какие-либо модификаторы, см.удар( демо ).
TCL( демо ),PostgreSQL( демо ),р(TRE, базовый двигатель по умолчанию R с не perl=TRUE
для базового R с perl=TRUE
или для stringr / STRINGI шаблонов, использовать (?s)
модификатор инлайн) ( демонстрационный ) также относиться к .
таким же образом.
Однако большинство инструментов на основе 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
включает в себя файл slurping, (?s)
включает режим DOTALL для .
шаблона, (?i)
включает режим без учета регистра, \K
пропускает сопоставленный текст до сих пор, *?
является ленивым квантификатором, (?=<Foobar>)
соответствует местоположению ранее <Foobar>
.pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file
(здесь M
включается слежка за файлами). Примечание pcregrep
- хорошее решение для grep
пользователей Mac OS .Двигатели без POSIX :
s
модификатор PCRE_DOTALL модификатор : preg_match('~(.*)<Foobar>~s', $s, $m)
( демо )RegexOptions.Singleline
флаг ( демо ): 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)
встроенную версию в начале) ( демо ):/(.*)<FooBar>/s
re.DOTALL
(или re.S
) флаги или (?s)
встроенный модификатор ( демо ): m = re.search(r"(.*)<FooBar>", s, flags=re.S)
(а затем if m:
, print(m.group(1))
)Pattern.DOTALL
модификатор (или встроенный (?s)
флаг) ( демо ):Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)
(?s)
модификатор in-pattern ( демо ):regex = /(?s)(.*)<FooBar>/
(?s)
модификатор ( демо ):"(?s)(.*)<Foobar>".r.findAllIn("abcde\n fghij<Foobar>").matchData foreach { m => println(m.group(1)) }
[^]
или обходные пути [\d\D]
/ [\w\W]
/ [\s\S]
( демо ):s.match(/([\s\S]*)<FooBar>/)[1]
std::regex
) Используйте [\s\S]
или обходные пути JS ( демо ):regex rex(R"(([\s\S]*)<FooBar>)");
УВА VBScript- Используйте тот же подход, что и в JavaScript ([\s\S]*)<Foobar>
. ( Примечание : MultiLine
свойство
RegExp
объекта иногда ошибочно считается вариант , чтобы .
матч через разрывы строк, в то время как, на самом деле, он изменяет только ^
и $
поведение , чтобы соответствовать начало / конец строки , а не строки , так же , как и в JS регулярное выражение ) поведение.)
Рубин- Использовать модификатор /m
MULTILINE ( демо ):s[/(.*)<Foobar>/m, 1]
(?s)
: regmatches(x, regexec("(?s)(.*)<FooBar>",x, perl=TRUE))[[1]][2]
( демо )stringr
/ stringi
regex, работающие на движке ICU regex, также используют (?s)
: stringr::str_match(x, "(?s)(.*)<FooBar>")[,2]
( demo )(?s)
в начале ( демо ):re: = regexp.MustCompile(`(?s)(.*)<FooBar>`)
dotMatchesLineSeparators
или (проще) передайте (?s)
встроенный модификатор в шаблон:let rx = "(?s)(.*)<Foobar>"
(?s)
работает проще всего, но вот как эта опция может быть использована :NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionDotMatchesLineSeparators error:®exError];
(?s)
модификатор ( демо ): "(?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-последовательности regex не поддерживаются в выражениях в скобках.[\s\S]
анализируется как выражения в скобках, которые соответствуют одному символу, \
или s
или S
.
#define MOD regex_constants::perl | boost::regex::no_mod_s | boost::regex::no_mod_m
для своих флагов регулярных выражений, чтобы отразить это. А арбитор всегда встроенные модификаторы. Где (?-sm)(?s).*
сбрасывает.
.
соответствует любому символу (включая разрывы строк). Посмотрите это онлайн демо Bash .
Go
в ответ!
Если вы используете поиск Eclipse, вы можете включить опцию "DOTALL", чтобы сделать '.' соответствует любому символу, включая разделители строк: просто добавьте «(? s)» в начале строки поиска. Пример:
(?s).*<FooBar>
(?s)
=>(?m)
Во многих диалектах регулярных выражений /[\S\s]*<Foobar>/
будет делать то, что вы хотите. Источник
([\s\S]*)<FooBar>
Точка соответствует всем кроме новых строк (\ r \ n). Поэтому используйте \ s \ S, который будет соответствовать ВСЕМ символам.
[text rangeOfString:regEx options:NSRegularExpressionSearch]
. Спасибо!
<FooBar>
В рубине РубинВы можете использовать m
опцию ' ' (многострочный):
/YOUR_REGEXP/m
См. Документацию Regexp на ruby-doc.org для получения дополнительной информации.
мы также можем использовать
(.*?\n)*?
чтобы соответствовать всем, включая перевод строки без жадных
Это сделает новую строку необязательной
(.*?|\n)*?
"."
обычно не соответствует переводу строки. Большинство движков регулярных выражений позволяет добавлять S
флаг (также называемый DOTALL
и SINGLELINE
), чтобы "."
также соответствовать символам новой строки. Если это не поможет, вы можете сделать что-то вроде [\S\s]
.
/(.*)<FooBar>/s
s приводит к тому, что точка (.) совпадает с возвратом каретки
s
флаги существует в PCRE, наиболее полный двигатель (доступен в Perl и PHP). PCRE имеет 10 флагов (и множество других функций), в то время как JavaScript имеет только 3 флага ( gmi
).
В регулярном выражении на основе Java вы можете использовать [\s\S]
s
флаг к шаблону в Java, а JavaScript не имеет s
флага.
Обратите внимание, что это (.|\n)*
может быть менее эффективно, чем (например) [\s\S]*
(если регулярные выражения вашего языка поддерживают такие экранированные символы), и чем найти способ определения используемого модификатора. также соответствуйте новым строкам. Или вы можете пойти с POSIXy альтернативы, как [[:space:][:^space:]]*
.
Используйте модификатор шаблона sU, чтобы получить желаемое совпадение в PHP.
preg_match('/(.*)/sU',$content,$match);
http://dreamluverz.com/developers-tools/regex-match-all-inclusive-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
(\s|\S)
кажется, добился цели!
(?s)
для .
сопоставления любых символов. Не используйте (\s|\S)
это замедлит производительность.
В 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>
\r
.:((?:.|\r?\n)*)<foobar>
Я хотел, чтобы соответствовать конкретный, если блок в 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 визуализирует регулярные выражения: