需要帮助Perl regex?

时间:2010-11-16 08:18:47

标签: regex perl parsing

这是我的文本文件表单。

S1,F2  title including several white spaces  (abbr) single,Here<->There,reply
S1,F2  title including several white spaces  (abbr) single,Here<->There
S1,F2  title including several white spaces  (abbr) single,Here<->There,[reply]

如何将我的注册表改为上述所有三种表格?

/^S(\d),F(\d)\s+(.*?)\((.*?)\)\s+(.*?),(.*?)[,](.*?)$/

我尝试用(.*?)$/替换[.*?]$/。它不起作用。我想我不应该使用[](方括号)来匹配[reply]的可能单词(包括[])。

实际上,我的一般问题应该是如何使用Perl在Reg exp中更好地匹配可能的字符?我查看了在线 PerlDoc 网页。但是我很难根据我的Perl知识水平找出有用的信息。这就是为什么我也问了一些愚蠢的问题。

感谢您的意见和建议。

4 个答案:

答案 0 :(得分:1)

您可以使用(?:..)? as:

使最后一部分成为可选部分
^S(\d),F(\d)\s+(.*?)\((.*?)\)\s+(.*?),(.*?)(?:,(.*))?$

Codepad link

答案 1 :(得分:1)

您知道正则表达式中的括号是保留用于声明要匹配的字符集吗?那么,对于一个真正的括号,你需要将其转义,或者将其括在括号中([[][]]),是不是被混淆了?!。

尝试(\[.*?\]|.*?)表示可选括号。

答案 2 :(得分:1)

尝试

/^S(\d),F(\d)\s+(.*?)\((.*?)\)\s+(.*?),(.*?)(,(\[reply\]|reply))?$/

这将匹配?,(\[reply\]|reply)的可选(,[reply])部分,reply,即

  • (无)
  • ,reply
  • [,reply]

顺便说一句,您的[,]表示“以下一个字符:,”。与正则表达式中的文字,完全相同。 如果您希望[,](.*?)$工作,则应使用(,(.+))?$匹配任何逗号后跟任何(非空)字符串。


编辑

如果以下内容也有效:

S1,F2  title including several white spaces  (abbr) single,Here<->There,[reply
S1,F2  title including several white spaces  (abbr) single,Here<->There,reply]

然后你可以在最后使用(,\[?reply\]?)?

答案 3 :(得分:1)

使用否定字符类怎么样:

 /^S(\d),F(\d)\s+([^()]*?)\s+\(([^()]+)\)\s+([^,]*),([^,]*)(?:,(.*?))?$/

合并到此脚本中时:

#!/bin/perl
use strict;
use warnings;
while (<>)
{
    chomp;
    my($s,$f,$title,$abbr,$single,$here,$reply) =
        $_ =~ m/^S(\d),F(\d)\s+([^()]*?)\s+\(([^()]+)\)\s+([^,]*),([^,]*)(?:,(.*?))?$/;
    $reply ||= "<no reply>";
    print "S$s F$f <$title> ($abbr) $single : $here : $reply\n";
}

在原始数据文件上运行,它会生成:

S1 F2 <title including several white spaces> (abbr) single : Here<->There : reply
S1 F2 <title including several white spaces> (abbr) single : Here<->There : <no reply>
S1 F2 <title including several white spaces> (abbr) single : Here<->There : [reply]

你应该也可以在表达式中使用'xms'后缀,以便更容易地记录它:

#!/bin/perl
use strict;
use warnings;

while (<>)
{
    chomp;

    my($s,$f,$title,$abbr,$single,$here,$reply) =
        $_ =~ m/^
                S(\d) ,             # S1
                F(\d) \s+           # F2
                ([^()]*?) \s+       # Title
                \(([^()]+)\) \s+    # (abbreviation)
                ([^,]*) ,           # Single
                ([^,]*)             # Here or There
                (?: , (.*?) )?      # Optional reply
                $
               /xms;

    $reply ||= "<no reply>";
    print "S$s F$f <$title> ($abbr) $single : $here : $reply\n";
}

我承认我仍然倾向于写一行怪物 - 我正试图修补我的方式。