I'm developing a piece of code to filter a text as follows:
<DATA>
.SUBCKT SVI A B C D E F
+ G H I
+ J K L
.....
+ X Y Z
*.PININFO AA BB CC
*.PININFO DD EE FF
<DATA>
I need the output to be
A B C D E F
G H I
J K L
.....
X Y Z
I already made a regular expression to do so:
m/\.SUBCKT\s+SVI\s(.*)|\+(.*)/gm
The problem is that I have many similar sections like this input but I only need to detect +
lines which are following .SUBCKT SVI
header not any other header.
How I could match group many times like (\\+\\s+(.*))
. I want to match this repeated capture group as it repeated many times.
Any advice to get this expression.
也许这更接近您的需求。
m/\.SUBCKT\s+SVI\s(.*)\n(\+\s+(.*)\n)*/gm
我利用@ shawnt00答案并修改了正则表达式,从而完成了工作。
\.SUBCKT\s+SVI_TRX201TH\s(.*\n(\+\s+.*\n)*)
Does this do what you want? Note that it stops at the .....
because it doesn't begin with a +
or .SUBCKT
It won't handle the case where a range of +
lines is immediately followed by another .SUBCKT
line; is that a problem?
use strict;
use warnings;
while ( <DATA> ) {
next unless my $in_range = s/^\.SUBCKT\s+// ... /^[^+]/;
next if $in_range =~ /E/;
s/^\S+\s+//;
print;
}
__DATA__
<DATA>
.SUBCKT SVI A B C D E F
+ G H I
+ J K L
.....
+ X Y Z
*.PININFO AA BB CC
*.PININFO DD EE FF
<DATA>
output
A B C D E F
G H I
J K L
Update
Here's a state machine version that deals with the special case described above
use strict;
use warnings;
my $state;
while ( <DATA> ) {
if ( /^\.SUBCKT\s+\S+\s+(.+)/ ) {
$state = 1;
print $1, "\n";
}
elsif ( /^\+\s+(.+)/ ) {
print $1, "\n" if $state;
}
else {
$state = 0;
}
}
__DATA__
<DATA>
.SUBCKT SVI A B C D E F
+ G H I
+ J K L
.SUBCKT SVI A B C D E F
+ M N O
+ P Q R
*.PININFO AA BB CC
*.PININFO DD EE FF
<DATA>
output
A B C D E F
G H I
J K L
A B C D E F
M N O
P Q R
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.