【问题标题】:perl regex to handle and preserver single and multiple words into a variableperl 正则表达式来处理和保存单个和多个单词到一个变量中
【发布时间】:2017-11-20 09:02:13
【问题描述】:

我正在编写一个 perl 脚本来读取成员的全名并将其保存到变量 firstname 和 lastname 中,如下所示:

my ($firstname, $lastname) = $member =~ m/^(\w+.*?) +(\w+)$/;
my $member_name = $firstname.' '.$lastname;

$member 的值来自上游服务,例如“Jane Doe” 现在,当服务发送像“Jane”这样的 $member 值时,上面的代码无法处理。正则表达式无法处理该代码行中的单个单词。我需要它来处理多个单词和单个单词。我无法实现新的代码功能,因此我希望添加到现有的正则表达式中,以便进行最小的更改并且它可以同时处理这两种情况。

到目前为止,这是我在命令行中测试的,但到目前为止还没有运气:

perl -e 'my ($firstname, $lastname) = "Jane Doe" =~ m/^(\w+.*?) +(\w+)$/|m/^(\w+)$/; print "$firstname\n$lastname";'

当我将“Jane Doe”替换为“Jane”时,什么也没有打印出来。我希望代码采用这种格式。就像值是多个单词一样,它应该同时打印它们,否则只打印一个单词。

您的帮助将不胜感激。

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    您的 Perl 代码中存在语法错误。您过早地终止了模式。

    #    /                 /   /      /   
    #                      V
        m/^(\w+.*?) +(\w+)$/|m/^(\w+)$/
    

    这将导致| 被解释为按位或。由于后面还有另一个m//| 将获取m// 操作的返回值并发挥其魔力。第二个m// 将与主题$_ 匹配。

    您真正想要的是合并两种模式。

    my ($firstname, $lastname) = "Jane Doe" =~ m/^(?:(\w+.*?) +)?(\w+)$/;
    

    您需要使用非捕获组(?:) 将名字设为可选,后跟? 无或单量词。

    您不能像您可能想要的那样拥有三个捕获组,因为第三个将转到$3,而不是$1

    但是,上述解决方案使用姓氏,然后将其分配给$firstname 变量。您的全名模式允许名称中包含任何字符,例如 Jean-Luc Picard。但是如果你只传入 Jean-Luc,匹配就会失败。因此,如果您只想要名字,则应使用正确的模式以使其保持一致。

    一个简单的方法是让姓氏成为可选的。

    my ($firstname, $lastname) = "Jane" =~ m/^(\w+.*?)(?: +(\w+))?$/;
    

    请记住,这会将$lastname 设置为undef,这在您的命令行示例中并不重要,但在具有strictwarnings 的适当程序中(您当然已经打开了) ,对吗?)如果$lastname 被用作字符串而它是undef,它会报错。


    我建议你阅读this article about names

    【讨论】:

    • 嗨@simbabque.. 非常感谢!给出的解决方案是有效的。您给出的正则表达式之一“my ($firstname, $lastname) = "Jane Doe" =~ m/^(?:(\w+.*?) +(\w+)|(\w+))$/;"虽然不工作。还有像你提到的那样我也可以处理特殊字符吗?
    • @Jahnavi 哦。我没有用一个 arg 测试第一个。第一个名称模式将进入$3,我的错误。对于那个很抱歉。我会修改的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    相关资源
    最近更新 更多