Perl 从复杂括号系统中提取字符串
我有一个字符串如下所示:Perl 从复杂括号系统中提取字符串,perl,Perl,我有一个字符串如下所示: (((Q,(P,(O,(M,N)))),(B,A)),C) 1|MN 2|MNO 3|MNOP 4|MNOPQ 5|BA 6|MNOPQBA 7|MNOPQBAC 我想把这封信放在括号里如下: (((Q,(P,(O,(M,N)))),(B,A)),C) 1|MN 2|MNO 3|MNOP 4|MNOPQ 5|BA 6|MNOPQBA 7|MNOPQBAC 我该怎么做?我是编程新手,开始用Perl编写代码,如有任何帮助,将不胜感激。谢谢 编写一个简单的解析器: s
(((Q,(P,(O,(M,N)))),(B,A)),C)
1|MN
2|MNO
3|MNOP
4|MNOPQ
5|BA
6|MNOPQBA
7|MNOPQBAC
我想把这封信放在括号里如下:
(((Q,(P,(O,(M,N)))),(B,A)),C)
1|MN
2|MNO
3|MNOP
4|MNOPQ
5|BA
6|MNOPQBA
7|MNOPQBAC
我该怎么做?我是编程新手,开始用Perl编写代码,如有任何帮助,将不胜感激。谢谢 编写一个简单的解析器:
sub parse {
my ($string_ref) = @_;
# check if the remaining string is a (x,y) group
if ($$string_ref =~ s/\A[(]//) {
my $first = parse($string_ref);
$$string_ref =~ s/\A[,]// or die "Expected a comma [,]";
my $second = parse($string_ref);
$$string_ref =~ s/\A[)]// or die "Expected a closing paren [)]";
return [$first, $second];
}
# check if we have a simple string
elsif ($$string_ref =~ s/\A([^,()]+)//) {
return $1;
}
else {
die "Expected [(] or [^,()]";
}
}
这是一个为嵌套零件调用自身的子例程。它接受对字符串的引用。要获取该引用中的字符串,我们必须取消对它的引用:$$reference
。要创建引用,我们使用\
操作符:$reference=\$value
=~s/../…/
将替换应用于字符串。在模式中,\A
固定在字符串的开头,而[…]
是一个字符类。因为替换的第二部分是空的,所以字符串开头的匹配部分被删除
现在my$str=“((Q,(p,(O,(M,N))),(B,A)),C)”;parse(\$str)
生成此数据结构:
[[["Q", ["P", ["O", ["M", "N"]]]], ["B", "A"]], "C"]
下一个问题是将此数据结构展平到字符串中。同样,我们可以编写一个递归解决方案,因为整平整个数据结构与整平此数据结构的一部分是相同的过程
sub flatten {
my ($data) = @_;
if (ref $data eq 'ARRAY') {
my ($first, $second) = @$data;
my ($first_str, @first_others ) = flatten($first );
my ($second_str, @second_others) = flatten($second);
my $str = $first_str . $second_str;
my @others = (@first_others, @second_others, $str);
return $str, @others;
}
elsif (ref $data eq '') {
return $data;
}
else {
die "Unknown data type ", ref $data;
}
}
ref
内置函数返回引用的类型。如果结果是空字符串,则该值不是引用(在本例中,它将是普通字符串)。上面的代码大量使用了列表分配:($x,@y)=(1,2,3)
分配数字,以便$x=1
和@y=(2,3)
。这也适用于数字较少的情况–如果($x,@y)=(1)
,则@y
将为空。还请注意,我们返回单个值(当展平字符串时)或多个值(当展平参数的内容时)
应用于该数据结构,我们得到以下列表:
(
"QPOMNBAC",
"MN",
"OMN",
"POMN",
"QPOMN",
"BA",
"QPOMNBA",
"QPOMNBAC",
)
那么我们怎样才能得到你想要的输出呢
use feature 'say';
my ($whole_string, @parts) = flatten(parse(\$str));
for my $i (0 .. $#parts) {
say $i + 1, "|", $parts[$i];
}
产生
1|MN
2|OMN
3|POMN
4|QPOMN
5|BA
6|QPOMNBA
7|QPOMNBAC
字符串中的顺序与所需的不同–您似乎已按字母顺序对每个paren中的部分进行了排序。为此,我们必须更改flatten
中的某些内容。但是,如果不知道要如何准确排序,这是不可能做到的。编写一个简单的解析器:
sub parse {
my ($string_ref) = @_;
# check if the remaining string is a (x,y) group
if ($$string_ref =~ s/\A[(]//) {
my $first = parse($string_ref);
$$string_ref =~ s/\A[,]// or die "Expected a comma [,]";
my $second = parse($string_ref);
$$string_ref =~ s/\A[)]// or die "Expected a closing paren [)]";
return [$first, $second];
}
# check if we have a simple string
elsif ($$string_ref =~ s/\A([^,()]+)//) {
return $1;
}
else {
die "Expected [(] or [^,()]";
}
}
这是一个为嵌套零件调用自身的子例程。它接受对字符串的引用。要获取该引用中的字符串,我们必须取消对它的引用:$$reference
。要创建引用,我们使用\
操作符:$reference=\$value
=~s/../…/
将替换应用于字符串。在模式中,\A
固定在字符串的开头,而[…]
是一个字符类。因为替换的第二部分是空的,所以字符串开头的匹配部分被删除
现在my$str=“((Q,(p,(O,(M,N))),(B,A)),C)”;parse(\$str)
生成此数据结构:
[[["Q", ["P", ["O", ["M", "N"]]]], ["B", "A"]], "C"]
下一个问题是将此数据结构展平到字符串中。同样,我们可以编写一个递归解决方案,因为整平整个数据结构与整平此数据结构的一部分是相同的过程
sub flatten {
my ($data) = @_;
if (ref $data eq 'ARRAY') {
my ($first, $second) = @$data;
my ($first_str, @first_others ) = flatten($first );
my ($second_str, @second_others) = flatten($second);
my $str = $first_str . $second_str;
my @others = (@first_others, @second_others, $str);
return $str, @others;
}
elsif (ref $data eq '') {
return $data;
}
else {
die "Unknown data type ", ref $data;
}
}
ref
内置函数返回引用的类型。如果结果是空字符串,则该值不是引用(在本例中,它将是普通字符串)。上面的代码大量使用了列表分配:($x,@y)=(1,2,3)
分配数字,以便$x=1
和@y=(2,3)
。这也适用于数字较少的情况–如果($x,@y)=(1)
,则@y
将为空。还请注意,我们返回单个值(当展平字符串时)或多个值(当展平参数的内容时)
应用于该数据结构,我们得到以下列表:
(
"QPOMNBAC",
"MN",
"OMN",
"POMN",
"QPOMN",
"BA",
"QPOMNBA",
"QPOMNBAC",
)
那么我们怎样才能得到你想要的输出呢
use feature 'say';
my ($whole_string, @parts) = flatten(parse(\$str));
for my $i (0 .. $#parts) {
say $i + 1, "|", $parts[$i];
}
产生
1|MN
2|OMN
3|POMN
4|QPOMN
5|BA
6|QPOMNBA
7|QPOMNBAC
字符串中的顺序与所需的不同–您似乎已按字母顺序对每个paren中的部分进行了排序。为此,我们必须更改
flatten
中的某些内容。但是,如果不知道要如何准确排序,这是不可能的。删除逗号并将结果作为参数提供给任何(大部分)lisp:)的读取函数。删除逗号并将结果作为参数提供给任何(大部分)lisp:)的读取函数。欢迎使用堆栈溢出!请花点时间阅读文档。虽然您的问题是关于编程的,但它要求我们完全解决您的问题。它看起来也很像家庭作业。家庭作业没什么问题,但你应该自己想想。通过让别人解决问题来作弊会在以后伤害到你。请花点时间考虑一下如何做到这一点。只要考虑一种方法/算法,如果不能在Perl中实现,就把它写下来。我们感谢这里的努力。:)欢迎来到堆栈溢出!请花点时间阅读文档。虽然您的问题是关于编程的,但它要求我们完全解决您的问题。它看起来也很像家庭作业。家庭作业没什么问题,但你应该自己想想。通过让别人解决问题来作弊会在以后伤害到你。请花点时间考虑一下如何做到这一点。只要考虑一种方法/算法,如果不能在Perl中实现,就把它写下来。我们感谢这里的努力。:)简洁的解释!“你今年要来吗?”辛巴基,谢谢。我不太确定我是否会去,但我当然想来。注册什么时候结束?请给我发邮件到meine hannover.pm地址。非常感谢!!字符串内部的顺序并不重要,真的很感谢。你太棒了,你能不能再设计一些,什么时候()被[]替换了?简洁的解释!你要来吗