【问题标题】:perl insert and or replace string variable into a stringperl 将字符串变量插入或替换成字符串
【发布时间】:2012-10-11 01:08:35
【问题描述】:

我的要求是检查一个字符串并根据特定的字符集插入或替换为前缀字符串

$prefix = "DV1";

以下是我的源 $input 字符串:

SS7.ABCWT2.RSND.LTE1.QR
IT4.ABCET2.VCE2.QR
Y88.ABCNT2.MIM.EDR2.QR
9C5.ABCS.MIM.EDR2.QR

first 之前的第一个字符。可以是任意长度 但在第一次之后。字符 ABC 保持不变,后跟任何一个字符 - 这四个字符将始终存在于我的输入字符串中。 在这 4 个字符之后,i/p 字符串可能有两个字母数字字符 - 在这种情况下为 T2。

需要做的是检查 $input 是否有“T2”(可以是任何两个字母数字字符),如果它有然后用 D1 替换这两个字符(来自 $prefix 的任何两个字符)

如果 $input 没有 "T2",则插入 $prefix

【问题讨论】:

  • 我不明白规范。您能否添加更多输入数据和预期输出或澄清算法?

标签: regex perl


【解决方案1】:

这可以通过一次替换非常简单地完成。这个程序演示了

该模式查找序列.ABC 后跟任何非点字符。 \K 保护模式的该部分不被更改。然后可能有两个可选的非点字符,后跟一个点。如果两个可选字符存在则替换字符串为D1,否则为$prefix 的值

use strict;
use warnings;

my $prefix = 'DV1';

while (<DATA>) {
  s/\.ABC[^.]\K([^.]{2})?(?=\.)/$1 ? 'D1' : $prefix/e;
  print;
}

__DATA__
SS7.ABCWT2.RSND.LTE1.QR
IT4.ABCET2.VCE2.QR
Y88.ABCNT2.MIM.EDR2.QR
9C5.ABCS.MIM.EDR2.QR

输出

SS7.ABCWD1.RSND.LTE1.QR
IT4.ABCED1.VCE2.QR
Y88.ABCND1.MIM.EDR2.QR
9C5.ABCSDV1.MIM.EDR2.QR

【讨论】:

  • @Borodin.. 想确认一下,您的while 不会将完整的文件加载到内存中吗?还是在foreach的情况下发生这种情况??
  • 感谢大师......我被困在这几个小时。 :)
  • 像这样的while (&lt;&gt;) { ... } 循环一次只读取一行数据。如果你写for (&lt;&gt;) { ... },那么 Perl 会将 整个 文件读入内存,然后循环遍历它存储的行
【解决方案2】:

这是你可以尝试的代码..

我假设,T2 可以是长度为 2 的任意字母数字字符的字符串。它可以是 A4 或 5B...

#!/perl/bin
use v5.14;
use warnings;

my $str = "9C5.ABCS.MIM.EDR2.QR";
my $str1 = "SS7.ABCWT2.RSND.LTE1.QR";

my $prefix = "DV1";

my $file = 'D:\Programming\Perl\Learning Perl\chapter_1\demo.txt';


open my $fh, '<', $file or die $!;

foreach (<$fh>) {

    if (m/(^.*\.ABC\w)\w{2}\./g) {
        s/(^.*\.ABC\w)\w{2}\./$1D1\./;
    } else {
        s/(^.*\.ABC\w)\./$1$prefix\./;
    }
    say;  # Takes current line as default($_). We don't need to specify it.
}

输入文件:-

SS7.ABCWT2.RSND.LTE1.QR
IT4.ABCEX4.VCE2.QR
Y88.ABCN5W.MIM.EDR2.QR
9C5.ABCS.MIM.EDR2.QR

输出:-

SS7.ABCWD1.RSND.LTE1.QR  # Replace T2
IT4.ABCED1.VCE2.QR       # Replace X4
Y88.ABCND1.MIM.EDR2.QR   # Replace 5W    
9C5.ABCSDV1.MIM.EDR2.QR  # Does not contains T2. Add DV1

【讨论】:

  • \w 模式匹配大小写字母、数字和下划线,因此它等价于[A-Za-z0-9_]。在[\w\d] 中再次包含数字是没有意义的。
  • @Borodin.. 我不知道.. 所以我应该用 [\w] 替换它吗??
  • @Borodin 你是对的.. 我交叉检查了.. 它有效.. 我相应地编辑了代码.. :)
  • @Borodin.. 其实我还在学习 Perl.. 所以,我一直在忘记东西.. 需要大量练习.. 谢谢 :)
  • @Borodin。
【解决方案3】:

试试下面的代码,告诉我它是否符合你的需要:

#!/usr/bin/perl -l

use strict;
use warnings;

my $text =<<EOF;
SS7.ABCWT2.RSND.LTE1.QR
IT4.ABCET2.VCE2.QR
Y88.ABCNT2.MIM.EDR2.QR
9C5.ABCS.MIM.EDR2.QR
EOF

my $prefix = "DV1";

for (split "\n", $text) {
    s/^(\w+\.ABC\w)T2/$1D1/ || s/^/$prefix/;
    print;
}

输出

SS7.ABCWD1.RSND.LTE1.QR
IT4.ABCED1.VCE2.QR
Y88.ABCND1.MIM.EDR2.QR
DV19C5.ABCS.MIM.EDR2.QR

【讨论】:

  • 此代码似乎没有执行如果 $input 没有“T2”,则插入 $prefix 规范的一部分
  • 告诉我我误解了什么比投反对票更有建设性
  • @sputnick.. 不是我的反对意见,但您颠倒了规范.. if $input does not have "T2", then insert $prefix -> 您已插入 D1,如果它包含 T2,则您已替换为 $prefix。但我认为这不值得投反对票..
猜你喜欢
  • 1970-01-01
  • 2020-07-09
  • 2017-03-18
  • 1970-01-01
  • 2013-02-16
  • 2017-01-17
  • 2014-12-03
  • 2019-02-08
相关资源
最近更新 更多