例如,这个正则表达式
(.*)<FooBar>
将匹配:
abcde<FooBar>
但是如何让它在多行中匹配呢?
abcde
fghij<FooBar>
答案 0 :(得分:285)
试试这个:
((.|\n)*)<FooBar>
它基本上表示“任何字符或换行符”重复零次或多次。
答案 1 :(得分:202)
这取决于语言,但应该有一个可以添加到正则表达式模式的修饰符。在PHP中它是:
/(.*)<FooBar>/s
最后的 s 会使点匹配所有字符,包括换行符。
答案 2 :(得分:65)
如果您正在使用Eclipse搜索,则可以启用“DOTALL”选项来制作“。”匹配任何字符,包括行分隔符:只需在搜索字符串的开头添加“(?s)”。示例:
(?s).*<FooBar>
答案 3 :(得分:54)
问题是,.
模式匹配任何字符吗?答案因发动机而异。主要区别在于该模式是由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的正则表达式语法中,默认情况下,点匹配换行符。 Boost的ECMAScript语法允许您使用regex_constants::no_mod_m
(source)将其关闭。
至于oracle(基于POSIX),请使用n
option(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
,对于带有perl=TRUE
或 stringr / stringi 模式的基数R,请使用(?s)
内联修饰符)(demo)同时处理{ {1}}以同样的方式。
然而,大多数基于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
会污染文件并激活“段落”模式&#39;其中Perl使用连续换行符(-000pe
)作为记录分隔符。\n\n
。在这里,grep -Poz '(?si)abc\K.*?(?=<Foobar>)' file
启用文件slurping,z
启用(?s)
模式的DOTALL模式,.
启用不区分大小写的模式,(?i)
省略到目前为止匹配的文本,\K
是一个懒惰的量词,*?
与(?=<Foobar>)
之前的位置匹配。<Foobar>
(pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file
允许文件在这里啜饮)。注意M
是Mac OS pcregrep
用户的理想解决方案。基于非POSIX的引擎:
grep
修饰符PCRE_DOTALL modifier:s
(demo)preg_match('~(.*)<Foobar>~s', $s, $m)
标记(demo):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
内嵌版本)(demo):(?s)
/(.*)<FooBar>/s
(或re.DOTALL
)个标记或re.S
内联修饰符(demo):(?s)
(然后{{ 1}},m = re.search(r"(.*)<FooBar>", s, flags=re.S)
)if m:
修饰符(或内联print(m.group(1))
标记)(demo):Pattern.DOTALL
(?s)
in-pattern修饰符(demo):Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)
(?s)
修饰符(demo):regex = /(?s)(.*)<FooBar>/
(?s)
或变通办法"(?s)(.*)<Foobar>".r.findAllIn("abcde\n fghij<Foobar>").matchData foreach { m => println(m.group(1)) }
/ [^]
/ [\d\D]
(demo):[\w\W]
[\s\S]
)使用s.match(/([\s\S]*)<FooBar>/)[1]
或JS解决方法(demo):std::regex
[\s\S]
相同的方法。/m
MULTILINE modifier(demo):regex rex(R"(([\s\S]*)<FooBar>)");
([\s\S]*)<Foobar>
demo):s[/(.*)<Foobar>/m, 1]
dotMatchesLineSeparators
或(更简单)将(?s)
内联修饰符传递给模式:re: = regexp.MustCompile(`(?s)(.*)<FooBar>`)
(?s)
最简单,但option can be used:let rx = "(?s)(.*)<Foobar>"
(?s)
修饰符(demo):NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionDotMatchesLineSeparators error:®exError];
(在Google Spreadsheets中,(?s)
) 关注"(?s)(.*)<Foobar>"
:
在大多数非POSIX引擎中,=REGEXEXTRACT(A2,"(?s)(.*)<Foobar>")
内联修饰符(或嵌入式标记选项)可用于强制(?s)
匹配换行符。
如果放置在模式的开头,(?s)
会更改模式中所有.
的行为。如果(?s)
位于开头之后的某个位置,则只有那些位于其右侧的.
会受到影响,除非这是传递给Python的模式{{1} }}。在Python (?s)
中,无论.
位置如何,整个模式re
都会受到影响。使用re
停止(?s)
效果。修改后的组可用于仅影响正则表达式模式的指定范围(例如,.
将使换行符中的第一个(?s)
匹配,而第二个(?-s)
仅匹配其余的线)。
POSIX note :
在非正则表达式引擎中,要匹配任何字符,可以使用Delim1(?s:.*?)\nDelim2.*
/ .*?
/ .*
构造。
在POSIX中,[\s\S]
不匹配任何字符(如JavaScript或任何非POSIX引擎),因为括号表达式中不支持正则表达式转义序列。 [\d\D]
被解析为与单个字符[\w\W]
或[\s\S]
或[\s\S]
匹配的括号表达式。
答案 4 :(得分:31)
在JavaScript中,使用/[\S\s]*<Foobar>/
。 Source
答案 5 :(得分:27)
([\s\S]*)<FooBar>
该点匹配除换行符之外的所有内容(\ r \ n)。所以使用\ s \ S,它将匹配所有字符。
答案 6 :(得分:18)
答案 7 :(得分:10)
我们也可以使用
(.*?\n)*?
匹配包括换行符在内的所有内容而无需贪婪
这将使新行为可选
(.*?|\n)*?
答案 8 :(得分:8)
"."
通常与换行符不匹配。大多数正则表达式引擎允许您添加S
- 标记(也称为DOTALL
和SINGLELINE
),以使"."
也匹配换行符。
如果失败,您可以执行[\S\s]
。
答案 9 :(得分:7)
对于Eclipse,使用以下表达式:
富
jadajada Bar“
正则表达式:
Foo[\S\s]{1,10}.*Bar*
答案 10 :(得分:5)
/(.*)<FooBar>/s
s导致Dot(。)匹配回车
答案 11 :(得分:4)
在基于java的正则表达式中,您可以使用[\s\S]
答案 12 :(得分:3)
请注意,(.|\n)*
的效率可能低于(例如)[\s\S]*
(如果您的语言的正则表达式支持此类转义),而不是查找如何指定生成的修饰符。也匹配换行符。或者你可以使用像[[:space:][:^space:]]*
这样的POSIXy替代品。
答案 13 :(得分:3)
使用RegexOptions.Singleline,它改变了含义。包括换行符
Regex.Replace(content,searchText,replaceText,RegexOptions.Singleline);
答案 14 :(得分:2)
使用模式修饰符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
答案 15 :(得分:1)
在语言中使用的上下文中,正则表达式作用于字符串,而不是行。所以你应该能够正常使用正则表达式,假设输入字符串有多行。
在这种情况下,给定的正则表达式将匹配整个字符串,因为“&lt; FooBar&gt;”存在。根据正则表达式实现的细节,$ 1值(从“(。*)”获得)将是“fghij”或“abcde \ nfghij”。正如其他人所说,一些实现允许您控制是否“。”将与换行符匹配,为您提供选择。
基于行的正则表达式通常用于像egrep这样的命令行。
答案 16 :(得分:1)
我遇到了同样的问题并且解决了它可能不是最好的方法,但它的工作原理。在我完成真正的比赛之前,我替换了所有换行符:
mystring= Regex.Replace(mystring, "\r\n", "")
我正在操纵HTML,所以在这种情况下换行并不重要。
我尝试了上述所有建议但没有运气,我正在使用.Net 3.5 FYI
答案 17 :(得分:1)
尝试:.*\n*.*<FooBar>
假设您还允许使用空白换行符。因为您允许<FooBar>
之前的任何字符都不能包含。
答案 18 :(得分:0)
通常我们必须修改一个子字符串,其中几个关键字分布在子字符串之前的行。考虑一个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")
并且替换工作正常。
答案 19 :(得分:0)
我想匹配java中的特定if块
...
...
if(isTrue){
doAction();
}
...
...
}
如果我使用regExp
if \(isTrue(.|\n)*}
它包含方法块的右括号,所以我使用了
if \(!isTrue([^}.]|\n)*}
从通配符匹配中排除右括号。
答案 20 :(得分:0)
((.|\n)*)<foobar>
答案 21 :(得分:0)
在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>
答案 22 :(得分:0)
通常在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
答案 23 :(得分:-1)