Наприклад, це регулярний вираз
(.*)<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>/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)
вбудований модифікатор ( демонстрацію ):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
/ stringi
regex, які працюють з двигуном регулярного генерування 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 візуалізує регулярні вирази: