我将如何将变量多行perl正则表达式与不同的规则相匹配



解析器 api(我不允许修改(给了我一个这种形式的字符串:

var1    var2  
var2continued var2continued   \
var2continued
var3
var3continued 
var3continued

我想使用正则表达式拆分此字符串,以便:

$1 = "var1";
$2 = "var2  
var2continued var2continued   \
var2continued"
$3 = "var3
var3continued 
var3continued"

基本上,第一个变量是 1 个或多个空格后的第一个非空格词,并在遇到空格时结束。

第二个变量从第一个变量之后的第一个非空格字符开始,直到行尾。如果最后一个字符是"\",请将下一行添加到第二个变量中(不要修剪 cur 行上最后一个字符和"\"之间的空格(。"\" 不应捕获下一行,但返回两个 "\"(无转义(。仅修剪最后一行的空格。

第三个变量是第二个变量之后的所有内容。

到目前为止,我已经能够想出这个正则表达式,它仅适用于 var2 和 var3 的一行

$my_re = qr/s+(S+)s+(S+)s+[n](.*)/
$text =~ /$my_re/

第一个单词,然后是换行符之前的所有内容,前面紧跟一个非斜杠;然后是所有其他内容

/s+ (S+) s+ (.*?[^\]) n (.*)/xs;

/s修饰符使.也与换行符匹配,在这里很关键(通常它不会(。/x修饰符使其忽略文字空格,因此我们可以使其更具可读性。


示例程序

use warnings;
use strict;
use feature 'say';
my $v = 
q(    var1    var2  
var2continued var2continued   \
var2continued
var3
var3continued 
var3continued);
$v =~ /s+ (S+) s+ (.*?[^\]) n (.*)/xs;
say ""$1"";  say '---';
say ""$2"";  say '---';
say ""$3""; 

指纹

"var1" --- "var2 \ var2续 var2续 var2续" --- "var3 var3续 \ var3续">

尝试以下代码(我对问题的看法(

use strict;
use warnings;
my $str = do { local $/; <DATA> };
print "INPUT:n[$str]n";
$str =~ /(w+)s+(.*?\\\s*w+)n(.+)/s;
#$str =~ /(w+)s+((?:.*?)\\\s+(?:w+)?)n(.+)/s;
print "n1: [$1]";
print "n2: [$2]";
print "n3: [$3]";
__DATA__
var1    var2  
var2continued var2continued   \
var2continued
var3
var3continued 
var3continued

输出

INPUT:
[    var1    var2  
var2continued var2continued   \
var2continued
var3
var3continued 
var3continued
]
1: [var1]
2: [var2  
var2continued var2continued   \
var2continued]
3: [var3
var3continued 
var3continued
]

没有一个答案适用于所有情况(2 和 3 是可选的(。我遇到了一个小问题,解析器在反斜杠后添加了空间。

我最终将文本拆分为一行数组。然后将其分成两部分(1 和 2 一起,3 单独(。然后我把它分开第一部分。我的实际代码分为多个函数,但我在下面进行了简化:

my $empty_re = qr/^s*$/;
my $def_re = qr/(.*?)((?:\{2})*)(\?)s*$/;
my $dual_token_re = qr/s*(S+)s*(.*)/s;
$text= "place text here"
my @lines = split /n/, $text;
my $i;
my $j;
my $def = "";
my $other;
# Get start capture
for($i=0;$i<=$#lines;$i++){
last if !($lines[$i] =~ /$empty_re/);
}
# Start definition capture
for($j=$i;$j<=$#lines;$j++) {
$lines[$j] =~ s/$def_re/$1$2/; # remove ending backquote if odd
last if !$3; # break if even backquotes
}
$def = join "n", @lines[$i..$j];
$j++;
# Get remaining text
if ($j <= $#lines) {
$other = join "n", (splice @lines, $j);
}
# $def has 1 and 2, $other has 3
$def =~ /$dual_token/
# now $1 and $2 has 1 and 2, $other has 3

相关内容

  • 没有找到相关文章

最新更新