1

给定文本

my $line = "[cytokine]<ADJVNT-PROP-0> signaling, which have not [to]<PREP> date been shown [to]<PREP> be [[regulat]<EXP-V-0>ed]<EXP-PP-V-0>";
my $line2 = "[Human [papillomavirus]<VACC-PROP-0>]<VACC-PROP-0> genotype [31]<NUM> does not [express]<EXP-V-0> detectable [microRNA]<MIR-0> levels [during]<PREP> latent or productive virus replication.";

我想要做的是删除所有不会<XXX> 导致此结果的内容:

Output 1: <ADJVNT-PROP-0><PREP><PREP><EXP-V-0><EXP-PP-V-0>
Output 2: <VACC-PROP-0><VACC-PROP-0><NUM><EXP-V-0><MIR-0><PREP>

但是为什么这个正则表达式失败了?正确的方法是什么?

s/[^<.*>]//g

这是完整的代码和可执行文件:https ://eval.in/50996

4

3 回答 3

2

您的替换s/[^<.*>]//g使用了一个字符类,它匹配任何不是开或闭尖括号、点或星号的单个字符。所以它将删除所有这些字符,只留下这四个字符之一。

尝试编写一个可以解决整个问题的所有事情的正则表达式有一种奇怪的热情。在这里找到包含在尖括号中的所有字符串并将它们连接在一起要容易得多,就像这样。

use strict;
use warnings;

use feature 'say';

my $line = "[cytokine]<ADJVNT-PROP-0> signaling, which have not [to]<PREP> date been shown [to]<PREP> be [[regulat]<EXP-V-0>ed]<EXP-PP-V-0>";
my $line2 = "[Human [papillomavirus]<VACC-PROP-0>]<VACC-PROP-0> genotype [31]<NUM> does not [express]<EXP-V-0> detectable [microRNA]<MIR-0> levels [during]<PREP> latent or productive virus replication.";

say join '', $line  =~ /<[^<>]*>/g;
say join '', $line2 =~ /<[^<>]*>/g;

输出

<ADJVNT-PROP-0><PREP><PREP><EXP-V-0><EXP-PP-V-0>
<VACC-PROP-0><VACC-PROP-0><NUM><EXP-V-0><MIR-0><PREP>
于 2013-09-27T05:42:14.470 回答
1

这也应该这样做。

s/[^><]+?(?=<|$)//g;

查看工作演示

于 2013-09-27T03:53:09.180 回答
0

你可以试试这个。

s/[^<]*(<[^>]+>)[^<]*/$1/g;
于 2013-09-27T02:29:24.293 回答