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

时间:2018-10-11 18:11:11

标签: 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";

3 个答案:

答案 0 :(得分:2)

#!/usr/bin/perl
use warnings;
use strict;
my $str = "cat 11052000 cow_and_owner_ 01011999 12031981 dog 22032011";
$str =~ s/\s*([a-z_]+)((?: \d+)+)/$1:$2\n/g;
print $str;

从样本输入中产生所需的输出。

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

答案 1 :(得分:0)

另一个变体-

button.setBackgroundTintList(ColorStateList.valueOf(Color.RED));

答案 2 :(得分:0)

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

  1. ([a-z]||\_)将匹配:

    • 一个小写ASCII字母(a到z);
    • 一个空字符串(两个|之间的空格;或
    • 一个下划线(用反斜杠转义是多余的)。

    要获取它(或数字的相应子表达式)以匹配一个序列 或更多字符,您需要在其后加上+

  2. 除非它在字符串的开头,否则
  3. ^([0-9])将不匹配。在那里它将匹配一个数字。


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

use strict;
use warnings;

my $bday = "cat 11052000 cow_and_owner_ 01011999 12031981 dog 22032011 cat[1] 01012018 dog3 02012018";

# capture groups:
#          $1------------------------\   $2-------------\
$bday =~ s/([A-Za-z][A-Za-z0-9_\[\]]*)\h+(\d+(?:\h+\d+)*)(?!\S)\s*/$1:$2\n/g;

print $bday;

将打印出

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;