在制表符分隔的文本文件中,我想仅匹配第24个选项卡后面包含“1”值的行。
现在,我的正则表达式似乎与我想要的匹配,但在行不匹配时断开
你能帮我改进一下吗?
/(?:.+?\t){24}1/
INT E_63 0 0 u Le Le DET:ART DET le ?? ADJ SENT DET:ART NOM ADV SENT DET NOM 1 ?? ?? ?? ?? ?? 0 0 0 0 0 1 ?? ?? ?? ?? ?? ??
INT E_63 0 0 u Le Le DET:ART DET le ?? ADJ SENT DET:ART NOM ADV SENT DET NOM 1 ?? ?? ?? ?? ?? 0 0 0 0 0 0 ?? ?? ?? ?? ?? ??
(第一行应该匹配,第二行不应该。)
答案 0 :(得分:3)
由于catastrophic backtracking因.
也匹配而且与标签字符匹配,因此正则表达式不起作用。再加上在具有嵌套量词的组之后有更多的子模式,并且没有^
锚点,灾难性的回溯即将到来。
你需要的是一个否定的字符类[^\t]
并将模式锚定在字符串的开头:
/^(?:[^\t]*\t){24}1/
请参阅regex demo。
注意:要将1
作为整个字词进行匹配,您可以考虑在其后面添加\b
或前瞻(?!\S)
。
<强>详情:
^
- 字符串的开头(?:[^\t]*\t){24}
- 24个序列
[^\t]*
- 除了标签字符\t
- 标签字符1
- 1
字符。答案 1 :(得分:2)
而不是使用正则表达式,你可以拆分它,检查第23个索引处的第24列,然后使用条件。
#!/usr/bin/perl
use strict;
use warnings;
open (my $fh, "<", '/path/to/tab_delem_file') or die "Could not open file $!";
while(<$fh>){
chomp;
my @line = split/\t/, $_; #split on tab
if ($line[23] == 1){
#do something
}
else ($line[23] == 1){
#do something else
}
}