Regex 使用perl连接、拆分和映射以创建新属性 my$str=”“; $str=~s#]*oldattribs=“([^”]*)”# my$fulcnt=$&; my$afids=$1; 我的@affs=(); 如果($afids=~m/\s+/){ @affs=split/\s/,$afid; my$jnafs=join“,”,map{$\u=~ s/[a-z]*///i,}@affs; ($fulcnt.“newattribs=\“$jnafs\”); } 否则{ ($fulcnt); } #eg;
我的输出:Regex 使用perl连接、拆分和映射以创建新属性 my$str=”“; $str=~s#]*oldattribs=“([^”]*)”# my$fulcnt=$&; my$afids=$1; 我的@affs=(); 如果($afids=~m/\s+/){ @affs=split/\s/,$afid; my$jnafs=join“,”,map{$\u=~ s/[a-z]*///i,}@affs; ($fulcnt.“newattribs=\“$jnafs\”); } 否则{ ($fulcnt); } #eg;,regex,perl,dictionary,Regex,Perl,Dictionary,我的输出: my $str = "<SampleElement oldattribs=\"sa1 sa2 sa3\">"; $str =~ s#<SampleElement[^>]*oldattribs="([^"]*)"# my $fulcnt=$&; my $afids=$1; my @affs = (); if($afids =~ m/\s+/) {
my $str = "<SampleElement oldattribs=\"sa1 sa2 sa3\">";
$str =~ s#<SampleElement[^>]*oldattribs="([^"]*)"#
my $fulcnt=$&;
my $afids=$1;
my @affs = ();
if($afids =~ m/\s+/) {
@affs = split /\s/, $afids;
my $jnafs = join ",", map { $_=~s/[a-z]*//i, } @affs;
($fulcnt." newattribs=\"$jnafs\"");
}
else {
($fulcnt);
}
#eg;
预期产出:
<SampleElement oldattribs="sa1 sa2 sa3" newattribs="1,1,1">
有人可能会指出我哪里做错了。提前谢谢。这里有一个简单的方法,可以从输入
$str
构建显示的输出
注意:输入是单引号,而不是双引号。因此,\“
在正则表达式中不是问题
<SampleElement oldattribs="sa1 sa2 sa3" newattribs="1,2,3">
my$str='';
#从中拉出“sa1 sa2 sa3”字符串
my($attrs)=$str=~/=\\”([^\\]+)/;#“。(关闭错误语法突出显示)
#从中生成“1,2,3”字符串
my$index=join',',map{/(\d+/})split',$attrs;
#在<>之间提取内容,以便添加到其中,然后将其放回一起
我的($content)=$str=~//;
我的$outout='';
这将提供所需的输出
如果您对此感兴趣,可以将其中一些语句组合成单个语句。比如说
my $str = '<SampleElement oldattribs=\"sa1 sa2 sa3\">';
# Pull 'sa1 sa2 sa3' string out of it
my ($attrs) = $str =~ /=\\"([^\\]+)/; # " # (turn off bad syntax highlight)
# Build '1,2,3' string from it
my $indices = join ',', map { /(\d+)/ } split ' ', $attrs;
# Extract content between < > so to add to it, put it back together
my ($content) = $str =~ /<(.*)>/;
my $outout = '<' . $content . " newattribs=\"$indices\"" . '>';
my$index=
连接“,”,映射{/(\d+/}拆分“”,($str=~/”([^\\]+)/)[0];#”
$str=~s//;
所有这些都可以合并到一个正则表达式中,但它变得非常笨拙,难以维护
最重要的是,这似乎是
XML
之类的。。。请不要用手,除非有一两个片段。有很多优秀的解析器。通过搜索map函数找到了解决方案:
my $indices =
join ',', map { /(\d+)/ } split ' ', ($str =~ /"([^\\]+)/)[0]; # "
$str =~ s/<(.*)>/<$1 newattribs=\"$indices\">/;
而不是
它的工作非常感谢大家。哪里出了问题比您想象的要早——您正在使用正则表达式解析XML。XML是上下文的,而正则表达式不是 因为这是在迭代
@affs
中的所有元素并修改它们。。。但是map
只是返回表达式的结果-它是1
,因为它起作用了
如果要更改@affs
,请执行以下操作:
map { $_=~s/[a-z]*//i, } @affs;
但是如果您不想,那么简单的答案是使用r
regex标志:
s/[a-z]*//i for @affs;
或者像我在我的例子中所做的那样:
map { s/[a-z]*//ir } @affs;
哪个正则表达式匹配并捕获字符串的数字部分,但结果是返回“捕获”文本 您不需要变量
$foo
,只需使用map{s/[a-z]*//i;${code>,因为perl 5.14甚至可以使用map{s/[a-z]*///ir}
,这很好,但是为什么去掉字母呢?您不能改为匹配数字,map{/(\d+//}
(参见我的答案)?此外,这当然遗漏了一些东西——正则表达式行在语法方面是错误的(它不起作用)。你能修复它,发布工作代码吗?在我看来,在map
中使用s
regex(没有r
标志)是非常糟糕的,因为它正在修改源数组,map
的要点是返回一个新的。这种修改应该通过for
IMO来完成-它同样高效,而且更清楚您正在做什么。不要尝试自己使用regexps进行解析,而是使用解析器。一行代码:。
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig -> parse ( \*DATA );
my $sample_elt = $twig -> get_xpath('//SampleElement',0);
my @old_att = split ( ' ', $sample_elt -> att('oldattribs') );
$sample_elt -> set_att('newattribs', join " ", map { /(\d+)/ } @old_att);
$twig -> set_pretty_print ( 'indented_a' );
$twig -> print;
__DATA__
<XML>
<SampleElement oldattribs="sa1 sa2 sa3">
</SampleElement>
</XML>
map { $_=~s/[a-z]*//i, } @affs;
s/[a-z]*//i for @affs;
map { s/[a-z]*//ir } @affs;
map { /(\d+)/ } @affs;