How Do I Match Any Character Across Multiple Lines in a Regular Expression?
For Example, This Regex (. *) Will Match: Abcde but How Do I Get It to Match Across Multiple Lines? Abcde Fghij 1 25 Answers Try This: ((. |\N)*) It Basically...
For example, this regex
(.*)<FooBar>
will match:
abcde<FooBar>
But how do I get it to match across multiple lines?
abcde
fghij<FooBar>
25 Answers
Try this:
((.|\n)*)<FooBar>
It basically says "any character or a newline" repeated zero or more times.
It depends on the language, but there should be a modifier that you can add to the regex pattern. In PHP it is:
/(.*)<FooBar>/s
The s at the end causes the dot to match all characters including newlines.
The question is, can the . pattern match any character? The answer varies from engine to engine. The main difference is whether the pattern is used by a POSIX or non-POSIX regex library.
A special note about lua-patterns: they are not considered regular expressions, but . matches any character there, the same as POSIX-based engines.
Another note on matlab and octave: the . matches any character by default (demo): str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match'); (tokens contain a abcde\n fghij item).
Also, in all of boost's regex grammars the dot matches line breaks by default. Boost's ECMAScript grammar allows you to turn this off with regex_constants::no_mod_m (source).
As for oracle (it is POSIX based), use the n option (demo): select regexp_substr('abcde' || chr(10) ||' fghij<Foobar>', '(.*)<Foobar>', 1, 1, 'n', 1) as results from dual
POSIX-based engines:
A mere . already matches line breaks, so there isn't a need to use any modifiers, see bash (demo).
The tcl (demo), postgresql (demo), r (TRE, base R default engine with no perl=TRUE, for base R with perl=TRUE or for stringr/stringi patterns, use the (?s) inline modifier) (demo) also treat . the same way.
However, most POSIX-based tools process input line by line. Hence, . does not match the line breaks just because they are not in scope. Here are some examples how to override this:
- sed - There are multiple workarounds. The most precise, but not very safe, is
sed 'H;1h;$!d;x; s/\(.*\)><Foobar>/\1/'(H;1h;$!d;x;slurps the file into memory). If whole lines must be included,sed '/start_pattern/,/end_pattern/d' file(removing from start will end with matched lines included) orsed '/start_pattern/,/end_pattern/{{//!d;};}' file(with matching lines excluded) can be considered. - perl -
perl -0pe 's/(.*)<FooBar>/$1/gs' <<< "$str"(-0slurps the whole file into memory,-pprints the file after applying the script given by-e). Note that using-000pewill slurp the file and activate 'paragraph mode' where Perl uses consecutive newlines (\n\n) as the record separator. - gnu-grep -
grep -Poz '(?si)abc\K.*?(?=<Foobar>)' file. Here,zenables file slurping,(?s)enables the DOTALL mode for the.pattern,(?i)enables case insensitive mode,\Komits the text matched so far,*?is a lazy quantifier,(?=<Foobar>)matches the location before<Foobar>. - pcregrep -
pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file(Menables file slurping here). Notepcregrepis a good solution for macOSgrepusers.
Non-POSIX-based engines:
php - Use the
smodifier PCRE_DOTALL modifier:preg_match('~(.*)<Foobar>~s', $s, $m)(demo)c# - Use
RegexOptions.Singlelineflag (demo):
-var result = Regex.Match(s, @"(.*)<Foobar>", RegexOptions.Singleline).Groups[1].Value;
-var result = Regex.Match(s, @"(?s)(.*)<Foobar>").Groups[1].Value;powershell - Use the
(?s)inline option:$s = "abcde`nfghij<FooBar>"; $s -match "(?s)(.*)<Foobar>"; $matches[1]perl - Use the
smodifier (or(?s)inline version at the start) (demo):/(.*)<FooBar>/spython - Use the
re.DOTALL(orre.S) flags or(?s)inline modifier (demo):m = re.search(r"(.*)<FooBar>", s, flags=re.S)(and thenif m:,print(m.group(1)))java - Use
Pattern.DOTALLmodifier (or inline(?s)flag) (demo):Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)kotlin - Use
RegexOption.DOT_MATCHES_ALL:"(.*)<FooBar>".toRegex(RegexOption.DOT_MATCHES_ALL)groovy - Use
(?s)in-pattern modifier (demo):regex = /(?s)(.*)<FooBar>/scala - Use
(?s)modifier (demo):"(?s)(.*)<Foobar>".r.findAllIn("abcde\n fghij<Foobar>").matchData foreach { m => println(m.group(1)) }javascript - Use
[^]or workarounds[\d\D]/[\w\W]/[\s\S](demo):s.match(/([\s\S]*)<FooBar>/)[1]c++ (
std::regex) Use[\s\S]or the JavaScript workarounds (demo):regex rex(R"(([\s\S]*)<FooBar>)");vba vbscript - Use the same approach as in JavaScript,
([\s\S]*)<Foobar>. (NOTE: TheMultiLineproperty of theRegExpobject is sometimes erroneously thought to be the option to allow.match across line breaks, while, in fact, it only changes the^and$behavior to match start/end of lines rather than strings, the same as in JavaScript regex) behavior.)ruby - Use the
/mMULTILINE modifier (demo):s[/(.*)<Foobar>/m, 1]rtrebase-r - Base R PCRE regexps - use
(?s):regmatches(x, regexec("(?s)(.*)<FooBar>",x, perl=TRUE))[[1]][2](demo)ricustringrstringi - in
stringr/stringiregex funtions that are powered with the ICU regex engine. Also use(?s):stringr::str_match(x, "(?s)(.*)<FooBar>")[,2](demo)go - Use the inline modifier
(?s)at the start (demo):re: = regexp.MustCompile(`(?s)(.*)<FooBar>`)swift - Use
dotMatchesLineSeparatorsor (easier) pass the(?s)inline modifier to the pattern:let rx = "(?s)(.*)<Foobar>"objective-c - The same as Swift.
(?s)works the easiest, but here is how the option can be used:NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionDotMatchesLineSeparators error:®exError];re2, google-apps-script - Use the
(?s)modifier (demo):"(?s)(.*)<Foobar>"(in Google Spreadsheets,=REGEXEXTRACT(A2,"(?s)(.*)<Foobar>"))
NOTES ON (?s):
In most non-POSIX engines, the (?s) inline modifier (or embedded flag option) can be used to enforce . to match line breaks.
If placed at the start of the pattern, (?s) changes the bahavior of all . in the pattern. If the (?s) is placed somewhere after the beginning, only those .s will be affected that are located to the right of it unless this is a pattern passed to Python's re. In Python re, regardless of the (?s) location, the whole pattern . is affected. The (?s) effect is stopped using (?-s). A modified group can be used to only affect a specified range of a regex pattern (e.g., Delim1(?s:.*?)\nDelim2.* will make the first .*? match across newlines and the second .* will only match the rest of the line).
POSIX note:
In non-POSIX regex engines, to match any character, [\s\S] / [\d\D] / [\w\W] constructs can be used.
In POSIX, [\s\S] is not matching any character (as in JavaScript or any non-POSIX engine), because regex escape sequences are not supported inside bracket expressions. [\s\S] is parsed as bracket expressions that match a single character, \ or s or S.
If you're using Eclipse search, you can enable the "DOTALL" option to make '.' match any character including line delimiters: just add "(?s)" at the beginning of your search string. Example:
(?s).*<FooBar>
In many regex dialects, /[\S\s]*<Foobar>/ will do just what you want. Source
([\s\S]*)<FooBar>
The dot matches all except newlines (\r\n). So use \s\S, which will match ALL characters.
In Ruby you can use the 'm' option (multiline):
/YOUR_REGEXP/m
See the Regexp documentation on ruby-doc.org for more information.
We can also use
(.*?\n)*?
to match everything including newline without being greedy.
This will make the new line optional
(.*?|\n)*?
"." normally doesn't match line-breaks. Most regex engines allows you to add the S-flag (also called DOTALL and SINGLELINE) to make "." also match newlines.
If that fails, you could do something like [\S\s].
For Eclipse, the following expression worked:
Foo
jadajada Bar"
Regular expression:
Foo[\S\s]{1,10}.*Bar*
Note that (.|\n)* can be less efficient than (for example) [\s\S]* (if your language's regexes support such escapes) and than finding how to specify the modifier that makes . also match newlines. Or you can go with POSIXy alternatives like [[:space:][:^space:]]*.
Use:
/(.*)<FooBar>/s
The s causes dot (.) to match carriage returns.
Use RegexOptions.Singleline. It changes the meaning of . to include newlines.
Regex.Replace(content, searchText, replaceText, RegexOptions.Singleline);
In a Java-based regular expression, you can use [\s\S].
Generally, . doesn't match newlines, so try ((.|\n)*)<foobar>.
In JavaScript you can use [^]* to search for zero to infinite characters, including line breaks.
$("#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=""></script>
<button id="find_and_replace">Find and replace</button>
<br>
<textarea ID="textarea">abcde
fghij<Foobar></textarea>
Must Read
Solution:
Use pattern modifier sU will get the desired matching in PHP.