【问题标题】:Performing a regex substitution Perl执行正则表达式替换 Perl
【发布时间】:2012-11-06 04:48:23
【问题描述】:

假设我有 IP 10.23.233.34,我想简单地将 233 换成 234。第一个、第二个和最后一个八位字节是未知的。第三个八位字节是233234。我想进行替换,使其与 IP、subs 匹配并保留其他所有内容,同时仍切换最后一个八位字节。例如:

输入:10.23.233.34

s/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){}233\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){}234\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/

输出:10.23.234.34

【问题讨论】:

标签: regex perl substring pcre


【解决方案1】:

这个问题确实不太适合正则表达式解决方案。相反,我会执行以下操作:

$in = "10.23.233.34";
@a = split /\./, $in;
if ($a[2] == '233') {
    $a[2] = '234';
}
print join(".", @a);

上面的代码比你想出的任何正则表达式都更具可读性。此外,下一个必须维护您的代码的人将能够真正阅读它。

【讨论】:

  • 这很好,假设您不必在修改字符串之前验证该字符串是否实际包含 IP 地址。此外,您有一个错字 - if 的条件应该是 ==,而不是 =
  • 问题是“假设我有 IP ......”所以我接受了这个假设。如果需要,验证输入格式是多行的。 (谢谢,修复了==。)
  • 我必须验证它是一个 IP。假设我有这样一行“嗨,我的 IP 是 10.23.233.34。我住在离纽约市 0.233 英里的建筑物 10.233 小节 0.233.34。哦,我的朋友 IP 是 10.33.233.55”我两个实例 10.23.233.34 都应该更改为10.23.234.34 和 10.33.233.55 应更改为 10.33.234.55。其他一切都应该留下来。 Ohh Greg 发布关于投票的问题有什么问题?它鼓励回答。
  • 简单总是更好。您还可以在正则表达式中使用嵌入式子例程来增加您的数字(或应用您将来可能需要的任何其他逻辑),但此解决方案有效并且更具可读性/可维护性。
【解决方案2】:

有时正则表达式会使事情变得脆弱且难以理解。尽管如此:

my $ip = '10.23.233.34';
...
for ($ip) {
    s!(?<=\.)233(?=\.\d+$)!234!;
}

详细信息:如果给定一个格式良好的点状四边形,则上面会在第三个八位字节中查找'233':前面是一个点,后面是一个点,然后是一个或多个数字,然后是字符串的结尾。 ?&lt;=?= 防止捕获除'233' 之外的任何内容,然后替换'234'。这种方法验证 IP 地址的格式是否正确。

【讨论】:

    【解决方案3】:
    $byte = qr/(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])/;
    s/($byte)\.($byte)\.(23[34])\.($byte)/join '.', $1, $2, 467-$3, $4/e;
    

    【讨论】:

      【解决方案4】:

      这是一个选项:

      use strict;
      use warnings;
      
      my $ip = '10.23.233.34';
      
      $ip =~ s/(\d+)(\.\d+)$/($1 == 233 ? $1+1 : $1) . $2/e;
      
      print $ip;
      

      输出:

      10.23.234.34
      

      【讨论】:

        猜你喜欢
        • 2017-08-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-27
        • 2018-10-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多