Наприклад, це регулярний вираз
(.*)<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.
Особлива примітка о луа-візерунки: вони не вважаються регулярними виразами, але .відповідають будь-яким символам, таких як двигуни на основі POSIX.
Ще одна примітка матлаб і октава: .відповідає будь-якому знаку за замовчуванням ( демо ): str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match');( tokensмістить abcde\n fghijелемент).
Також у всіх прискоренняграматики з регулярними виразами крапки розбивають рядки за замовчуванням. Граматика ECMAScript Boost дозволяє вимкнути це 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 :
Простий .вже відповідає розривам рядків, не потрібно використовувати будь-які модифікатори, дивбаш( демонстрація ).
The ткл( демонстрація ),postgresql( демонстрація ),r(TRE, базовий двигун за замовчуванням без 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файлів, (?s)увімкнено режим DOTALL для .шаблону, увімкнення режиму (?i)нечутливості до регістру, \Kвідмовлення від відповідного тексту досі, *?ледачий кількісний показник, (?=<Foobar>)відповідає розташуванню раніше<Foobar> .pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file( Mтут вмикається розбиття файлів). Примітка pcregrep- це гарне рішення для grepкористувачів ОС Mac .Двигуни на основі 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>/sre.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)вбудований модифікатор ( демонстрацію ):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>)");vba vbscript- Використовуйте той же підхід , як і в JavaScript, ([\s\S]*)<Foobar>. ( ПРИМІТКА . MultiLineВластивість
RegExpоб'єкта іноді помилково вважається можливістю дозволити .збіг між розривами рядків, в той час, як насправді він лише змінює ^та $поведінку на відповідність початку / кінця рядків, а не рядків , як у JS regex ) поведінка.)
рубін- Використовуйте модифікатор /m MULTILINE ( демонстрацію ):s[/(.*)<Foobar>/m, 1]
(?s): regmatches(x, regexec("(?s)(.*)<FooBar>",x, perl=TRUE))[[1]][2]( демонстрація )stringr/ stringiregex, які працюють з двигуном регулярного генерування ICU, також використовується (?s): stringr::str_match(x, "(?s)(.*)<FooBar>")[,2]( демонстрація )(?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), оскільки послідовності виведення регулярних виразів не підтримуються у виразах дужок. [\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регексу дозволяє додавати -flag (також називається 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-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
(\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>
Часто нам доводиться змінювати підрядку з кількома ключовими словами, розкинутими по рядках, що передують підрядковій. Розглянемо елемент 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 візуалізує регулярні вирази: