#!/usr/bin/perl
use strict;
use warnings;
my $string = "[p1 text1/label1] [p2 text2/label2] textX/labelX [p3 text3/label3] [...] textY/labelY textZ/labelZ [...]";
# don't split inside the [], i.e. not at blanks that have p\d in front of them
my @items = split(/(?<!p\d)\s+/, $string);
my @new_items;
# modify the items that are not inside []
@new_items = map { ($_ =~ m/\[/) ? $_ :
((split("/",$_))[1] eq ("IN")) ? "[PP $_]" :
"[BLA $_]";
} @items;
print join(' ', @new_items), "\n";
Это дает
[p1 text1/label1] [p2 text2/label2] [PP textX/labelX] [p3 text3/label3] [...] [PP textY/labelY] [PP textZ/labelZ] [...]
Я понял, что PP
имел в виду, как я использовал это здесь, иначе map
придется немного усложнить.
РЕДАКТИРОВАТЬ
Я отредактировал код в ответ на ваш комментарий.Если вы используете
"[p1 text1/label1] [p2 text2/label2] textX/IN [p3 text3/label3] [...] textY/labelY textZ/labelZ [...]";
в качестве образца строки, это будет вывод:
[p1 text1/label1] [p2 text2/label2] [PP textX/IN] [p3 text3/label3] [...] [BLA textY/labelY] [BLA textZ/labelZ] [...]
Только одна вещь, которую нужно иметь в виду: регулярное выражение, используемое с split
, не будет работать дляpn
при n> 9. Если у вас есть такие случаи, лучше всего искать альтернативу, потому что задние части переменной длины не были реализованы (или, по крайней мере, в моей версии Perl (5.10.1) они не реализованы).
РЕДАКТИРОВАТЬ 2
В качестве ответа на ваш второй комментарий, вот модифицированная версия скрипта.Вы обнаружите, что я также добавил что-то в пример строки, чтобы продемонстрировать, что она теперь работает, даже если внутри [...]
.
#!/usr/bin/perl
use strict;
use warnings;
my $string = "[p1 text1/label1] [p2 text2/label2] textX/IN [p3 text3/label3] [...] textY/labelY textZ/labelZ [...] xyx/IN [opq rs/abc]";
# we're using a non-greedy match to only capture the contents of one set of [],
# otherwise we'd simply match everything between the first [ and the last ].
# The parentheses around the match ensure that our delimiter is KEPT.
my @items = split(/(\[.+?\])/, $string);
#print "..$_--\n" for @items; # uncomment this to see what the split result looks like
# modify the items that are not inside []
my @new_items = map {
if (/^\[/) { # items in []
$_;
}
elsif (/(?: \w)|(?:\w )/) { # an arbitrary number of items without []
my @new = map { ($_ =~ m/\[/) ? $_ :
((split("/",$_))[1] eq ("IN")) ? "[PP $_]" :
"[BLA $_]";
} split;
}
else { # some items are '', let's just discard those
}
} @items;
print join(' ', @new_items), "\n";
нет *1031* Вывод такой:
[p1 text1/label1] [p2 text2/label2] [PP textX/IN] [p3 text3/label3] [...] [BLA textY/labelY] [BLA textZ/labelZ] [...] [PP xyx/IN] [opq rs/abc]
Я заметил, что вы уже получили необходимую вам помощь, но я думал, что смогу ответить на ваш вопрос все же ...