Perl 如何在单词和数字之间插入冒号

Perl 如何在单词和数字之间插入冒号,perl,Perl,我想在单词和数字之间插入一个冒号,然后在数字后面添加一个新行。 例如: "cat 11052000 cow_and_owner_ 01011999 12031981 dog 22032011"; 我的预期产出: cat:11052000 cow_and_owner_:01011999 12031981 dog:22032011 我的尝试: $Bday=~ /^([a-z]||\_)/:/^([0-9])/ print "\n"; 从示例输入生成所需的输出 编辑:注意使用s操作符替换正则表达

我想在单词和数字之间插入一个冒号,然后在数字后面添加一个新行。 例如:

"cat 11052000 cow_and_owner_ 01011999 12031981 dog 22032011";
我的预期产出:

cat:11052000
cow_and_owner_:01011999 12031981
dog:22032011
我的尝试:

$Bday=~ /^([a-z]||\_)/:/^([0-9])/
print "\n";
从示例输入生成所需的输出

编辑:注意使用
s
操作符替换正则表达式。代码中的许多问题之一是您没有使用它(如果您的目的是在适当的位置修改字符串,而不是从中提取位进行进一步处理)

还有一个变体-

> cat test_perl.pl
#!/usr/bin/perl
use strict;
use warnings;
while ( "cat 11052000 cow_and_owner_ 01011999 12031981 dog 22032011" =~ m/([a-z_]+)\s+([0-9 ]+)/g )
{
print "$1:$2\n";
}
> test_perl.pl
cat:11052000
cow_and_owner_:01011999 12031981
dog:22032011
>

原始代码
$Bday=~/^([a-z]| | \\\\\\/:/^([0-9])/
没有多大意义。除了缺少分号和分隔符过多(匹配模式的格式为
/…/
m/../../
并替换为
s/../../
),它永远无法匹配任何内容

  • ([a-z]| | \\)
    将匹配:

    • 一个小写ASCII字母(a到z)
    • 空字符串(两个
      |
      之间的空格;或
    • 一个下划线(用反斜杠转义是多余的)
    使其(或相应的数字子表达式)匹配一个一的序列 或多个字符,您需要在其后面加一个
    +

  • ^([0-9])
    将无法匹配,除非它位于字符串的开头。在那里,它将匹配一位数字


  • 我的解决方案(考虑到OP稍后关于输入的评论,例如
    cat[1]
    dog3
    ):

    将打印:

    cat:11052000
    cow_and_owner_:01011999 12031981
    dog:22032011
    cat[1]:01012018
    dog3:02012018
    
    细分:

    • [A-Za-z]
      :以字母开头

    • [A-Za-z0-9\[\]*
      :后跟零个或多个字母、数字、下划线和方括号

    • \h+
      :用一个或多个水平空格分隔

    • \d+(?:\h+\d+*
      :一个数字序列(
      \d+
      ),后跟零个或多个水平空格和数字序列

    • (?!\S)
      :后面不能跟非空白

    • \s*
      :使用以下空白(包括换行符;这允许在多行上分隔输入,只要单个条目不分散在多行上。要获得此结果,请将所有
      \h+
      替换为
      \s+

    只要匹配,“替换”模式将在源字符串中按顺序重复(“代码>/g修饰符”),将每个标题日期记录放在其自己的行上,然后继续处理字符串的其余部分


    请注意,如果您的标题(
    dog
    等)可能包含非ASCII字母,请使用
    \pL
    \p{XPosixAlpha}
    而不是
    [A-Za-z]

    $bday =~ s/\pL[\pL0-9_\[\]]*)\h+(\d+(?:\h+\d+)*)(?!\S)\s*/$1:$2\n/g;
    

    运行代码时会发生什么情况?结果是什么?您的示例只是打印一个换行符。当然,您不需要打印“$Bday\n”。正如@Matt所问的,您的结果是什么以及它是如何出错的?很抱歉,Matt和Carl,我在script.pl第13行“/^([a-z]| |/:”附近遇到语法错误谢谢Shawn,你的代码运行得很好。是的,我刚刚意识到我的代码中缺少s运算符。但是,如果“cat”改为“cat[1]”,而“dog”改为“dog3”,我的代码就无法得到输出。我尝试使用:str=~s/\s*([a-zA-Z0-9_]]+)((?:\d+)/$1:$2\n/g;但我得到的是cat[]:11052000”\n牛和牛的主人狗3:22032011。我可以知道括号中“:”的含义吗?如果您能帮忙,我将不胜感激explain@thx94常规的
    (…)
    是一个捕获组,这意味着内容将根据出现的顺序放置在变量
    $1
    $2
    等中。
    (?:…)
    使组不可捕获,允许您仅分组、乘法或生成可选的复杂对象而不捕获它们。例如,要匹配单词“child”或复数“children”,您可以使用正则表达式模式
    /\bchild(?:ren)?\b/
    ,将“ren”分组并使其作为一个整体可选(并不是每个字母都单独出现)。大多数情况下,除非检查复数是否存在,否则您不想捕获“ren”。(需要使用
    \b
    或其他一些检查单词边界的方法来避免匹配“childless”或“Fairchild”。)
    cat:11052000
    cow_and_owner_:01011999 12031981
    dog:22032011
    cat[1]:01012018
    dog3:02012018
    
    $bday =~ s/\pL[\pL0-9_\[\]]*)\h+(\d+(?:\h+\d+)*)(?!\S)\s*/$1:$2\n/g;