用于获取标签的第一个实例和最后一个实例之间的所有内容的正则表达式
Regex for getting Everything Between First and Last Instance of Tags
我正在项目中使用一些 Blade 语法,我需要手动解析 foreach 循环的内容。语法实际上看起来像:
@foreach
@foreach
Text
@endforeach
@endforeach
我需要找到一个正则表达式字符串来获取第一个 @foreach/@endforeach
包含的所有内容
我已经尝试过 "@foreach(.*?)@endforeach"
,但是在第一个 @endforeach
时就被捕获了。
此正则表达式示例的预期输出为:
@foreach
Text
@endforeach
这是我想出的(在 JavaScript)
let str = `@foreach
@foreach
Text
@endforeach
@endforeach`;
let result = str.match(/^\@foreach[\s\n]+([a-zA-Z0-9@\s\n]+)\@endforeach$/);
console.log(result[1]);//@foreach Text @endforeach
\@foreach[\s\n]+
=>遍历第一个@foreach
([a-zA-Z0-9@\s\n]+)
=> 抓住它之后的一切
\@endforeach$
=> 确保一个@endforeach 遗漏
http://www.rexegg.com/regex-lookarounds.html
你的正则表达式停在第一个 @endforeach
的原因是因为 .*?
中的 ?
使它成为一个 lazy 量词,意思是正则表达式将使用尽可能少的字符。省略 ?
使其成为一个贪婪的量词,它将使用尽可能多的字符。
@foreach[\s\S]*@endforeach
,让你的正则表达式变得贪婪,匹配整个字符串。
如果您想要介于两者之间的一切,您可能需要使用先行和后行。
(?<=@foreach)[\s\S]*(?=@endforeach)
捕获所有内容,包括第一个 @foreach
.
之后的换行符
但是,如果在第一个循环之外还有更多 @foreach
循环,这将中断。例如
@foreach
Text
@endforeach
@foreach
More text
@endforeach
是的,正则表达式搜索在找到第一个 @endforeach 时停止。要获得您想要的内容,请使用 {1,} 表示该模式中的一个或多个:
(@foreach)(.*?)(@endforeach){1,}
但在这种情况下,我建议您使用 substr 和 strpos() 以及 strrpos 代替正则表达式:
<?php
$blade_str = "
Some Template content before loop
@foreach
@foreach
Some text in loop
@endforeach
@endforeach
some content after loop";
$loop_str = substr($blade_str, strpos($blade_str , '@foreach'));
print("\nloop_str=" . $loop_str);
// grab start of text after first @foreach
$inner_str = substr($loop_str, 8); // @foreach is 8 chars
// strip out last @endforeach
$inner_str = substr($inner_str, 0, strrpos($inner_str, '@endforeach'));
print("\ninner_str=" . $inner_str);
在 http://phptester.net/ 上进行测试,您将获得以下结果:
loop_str=@foreach @foreach Some text in loop @endforeach @endforeach some content after loop
inner_str= @foreach Some text in loop @endforeach
祝你好运!
这个正则表达式可以解决问题
(?<=@foreach).*(?=@endforeach)
我在创建它的网站上创建了一个 link,您还可以在那里生成代码以在不同语言中使用此正则表达式(Java脚本,Java , PHP, Python, 和其他一些)
我正在项目中使用一些 Blade 语法,我需要手动解析 foreach 循环的内容。语法实际上看起来像:
@foreach
@foreach
Text
@endforeach
@endforeach
我需要找到一个正则表达式字符串来获取第一个 @foreach/@endforeach
我已经尝试过 "@foreach(.*?)@endforeach"
,但是在第一个 @endforeach
时就被捕获了。
此正则表达式示例的预期输出为:
@foreach
Text
@endforeach
这是我想出的(在 JavaScript)
let str = `@foreach
@foreach
Text
@endforeach
@endforeach`;
let result = str.match(/^\@foreach[\s\n]+([a-zA-Z0-9@\s\n]+)\@endforeach$/);
console.log(result[1]);//@foreach Text @endforeach
\@foreach[\s\n]+
=>遍历第一个@foreach
([a-zA-Z0-9@\s\n]+)
=> 抓住它之后的一切
\@endforeach$
=> 确保一个@endforeach 遗漏
http://www.rexegg.com/regex-lookarounds.html
你的正则表达式停在第一个 @endforeach
的原因是因为 .*?
中的 ?
使它成为一个 lazy 量词,意思是正则表达式将使用尽可能少的字符。省略 ?
使其成为一个贪婪的量词,它将使用尽可能多的字符。
@foreach[\s\S]*@endforeach
,让你的正则表达式变得贪婪,匹配整个字符串。
如果您想要介于两者之间的一切,您可能需要使用先行和后行。
(?<=@foreach)[\s\S]*(?=@endforeach)
捕获所有内容,包括第一个 @foreach
.
但是,如果在第一个循环之外还有更多 @foreach
循环,这将中断。例如
@foreach
Text
@endforeach
@foreach
More text
@endforeach
是的,正则表达式搜索在找到第一个 @endforeach 时停止。要获得您想要的内容,请使用 {1,} 表示该模式中的一个或多个:
(@foreach)(.*?)(@endforeach){1,}
但在这种情况下,我建议您使用 substr 和 strpos() 以及 strrpos 代替正则表达式:
<?php
$blade_str = "
Some Template content before loop
@foreach
@foreach
Some text in loop
@endforeach
@endforeach
some content after loop";
$loop_str = substr($blade_str, strpos($blade_str , '@foreach'));
print("\nloop_str=" . $loop_str);
// grab start of text after first @foreach
$inner_str = substr($loop_str, 8); // @foreach is 8 chars
// strip out last @endforeach
$inner_str = substr($inner_str, 0, strrpos($inner_str, '@endforeach'));
print("\ninner_str=" . $inner_str);
在 http://phptester.net/ 上进行测试,您将获得以下结果:
loop_str=@foreach @foreach Some text in loop @endforeach @endforeach some content after loop
inner_str= @foreach Some text in loop @endforeach
祝你好运!
这个正则表达式可以解决问题
(?<=@foreach).*(?=@endforeach)
我在创建它的网站上创建了一个 link,您还可以在那里生成代码以在不同语言中使用此正则表达式(Java脚本,Java , PHP, Python, 和其他一些)