在多行中捕获相同的正则表达式
Capturing the same regular expression over multiple lines
我想捕获一系列文件名,每个文件名都在新行中列出,我已经想出了如何在第一行捕获文件名,但我还没有想出如何重复它随后的几行。
# Input
# data/raw/file1
# data/raw/file2
# Output
# data/interim/file1
# data/interim/file2
当前尝试
我目前的正则表达式是
# Input\n(# (.*))
我的内部捕获组正确地捕获了 data/raw/file1
。
期望输出
我想要的是抓取# Input
和# Output
之间的所有文件,所以在这个例子中,data/raw/file1
和data/raw/file2
.
使用\G
魔法:
(?:^#\s+Input|\G(?!\A))\R*(?!#\s+Output)#\s*(.*)|[\s\S]*
正则表达式分解
(?: # Start of non-capturing group (a)
^#\s+Input # Match a line beginning with `# Input`
| # Or
\G(?!\A) # Continue from previous successful match point
) # End of NCG (a)
\R* # Match any kind of newline characters
(?!#\s+Output) # Which are not followed by such a line `# Output`
#\s*(.*) # Start matching a path line and capture path
| # If previous patterns didn't match....
[\s\S]* # Then match everything else up to end to not involve engine a lot
PHP代码:
$re = '~(?:^#\s+Input|\G(?!\A))\R*(?!#\s+Output)#\s*(.*)|[\s\S]*~m';
$str = '# Input
# data/raw/file1
# data/raw/file2
# Output
# data/interim/file1
# data/interim/file2';
preg_match_all($re, $str, $matches, PREG_PATTERN_ORDER, 0);
// Print the entire match result
print_r(array_filter($matches[1]));
输出:
Array
(
[0] => data/raw/file1
[1] => data/raw/file2
)
使用 s
修饰符、preg_match
和 preg_split
您可以单独获得每个结果。
preg_match('/# Input\n(# (?:.*?))# Output/s', '# Input
# data/raw/file1
# data/raw/file2
# Output
# data/interim/file1
# data/interim/file2', $match);
$matched = preg_split('/# /', $match[1], -1, PREG_SPLIT_NO_EMPTY);
print_r($matched);
正则表达式演示:https://regex101.com/r/5tfJGM/1/
我想捕获一系列文件名,每个文件名都在新行中列出,我已经想出了如何在第一行捕获文件名,但我还没有想出如何重复它随后的几行。
# Input
# data/raw/file1
# data/raw/file2
# Output
# data/interim/file1
# data/interim/file2
当前尝试
我目前的正则表达式是
# Input\n(# (.*))
我的内部捕获组正确地捕获了 data/raw/file1
。
期望输出
我想要的是抓取# Input
和# Output
之间的所有文件,所以在这个例子中,data/raw/file1
和data/raw/file2
.
使用\G
魔法:
(?:^#\s+Input|\G(?!\A))\R*(?!#\s+Output)#\s*(.*)|[\s\S]*
正则表达式分解
(?: # Start of non-capturing group (a)
^#\s+Input # Match a line beginning with `# Input`
| # Or
\G(?!\A) # Continue from previous successful match point
) # End of NCG (a)
\R* # Match any kind of newline characters
(?!#\s+Output) # Which are not followed by such a line `# Output`
#\s*(.*) # Start matching a path line and capture path
| # If previous patterns didn't match....
[\s\S]* # Then match everything else up to end to not involve engine a lot
PHP代码:
$re = '~(?:^#\s+Input|\G(?!\A))\R*(?!#\s+Output)#\s*(.*)|[\s\S]*~m';
$str = '# Input
# data/raw/file1
# data/raw/file2
# Output
# data/interim/file1
# data/interim/file2';
preg_match_all($re, $str, $matches, PREG_PATTERN_ORDER, 0);
// Print the entire match result
print_r(array_filter($matches[1]));
输出:
Array
(
[0] => data/raw/file1
[1] => data/raw/file2
)
使用 s
修饰符、preg_match
和 preg_split
您可以单独获得每个结果。
preg_match('/# Input\n(# (?:.*?))# Output/s', '# Input
# data/raw/file1
# data/raw/file2
# Output
# data/interim/file1
# data/interim/file2', $match);
$matched = preg_split('/# /', $match[1], -1, PREG_SPLIT_NO_EMPTY);
print_r($matched);
正则表达式演示:https://regex101.com/r/5tfJGM/1/