【问题标题】:How to properly chain Perl substitutions如何正确链接 Perl 替换
【发布时间】:2020-07-06 13:02:40
【问题描述】:

我注意到直接在终端中时很容易将替换链接在一起:

perl -p -i -e 's/\xa/\xd/g; s/(<ACROSS PUZZLE>.+<GRID>\r\t)([A-Z\.]{15,})(\r\t.+)/\2/g' _temp.txt;

但是,当我重写我拥有的一些脚本时,我没有成功将两个替换组合在一起。目前,作为两个单独的语句,它可以工作,但我不确定如何将这两行组合在一起:

$thisGrid =~ s/\xa/\xd/g;
$thisGrid =~ s/(<ACROSS PUZZLE>.+<GRID>\r\t)([A-Z\.]{15,})(\r\t.+)/\2/g; 

首先我尝试过:

$thisGrid =~ s/\xa/\xd/g =~ s/(<ACROSS PUZZLE>.+<GRID>\r\t)([A-Z\.]{15,})(\r\t.+)/\2/g; 

这似乎不起作用。

其他类似的主题似乎没有回答我的问题。

【问题讨论】:

  • -e 代码中,在命令/语句方面也有两条“行”,请注意;。如果需要,您还可以删除脚本中的换行符,使其成为文本行的“行”。虽然那时读起来更糟......问题是你想要在这里实现什么?如果中间没有新的界限,你希望会发生什么?
  • 正如sticky bit 指出的那样,perl oneliner 使用两个单独的命令进行替换——; 表示先执行左侧部分然后执行右侧部分。链接没有任何优势,除非首先产生结果 true 然后才执行第二个 - s/old/new/ if s/very_old/newer/;s/very_old/newer/ &amp;&amp; s/old/new。您的案例不属于此类 - 代码是线性:执行第一次替换,然后执行第二次替换。
  • 也不清楚为什么你使用s/(&lt;ACROSS PUZZLE&gt;.+&lt;GRID&gt;\r\t)([A-Z\.]{15,})(\r\t.+)/\2/g而不是s/&lt;ACROSS PUZZLE&gt;.+&lt;GRID&gt;\r\t([A-Z\.]{15,})\r\t.+/\1/g。如果结果没有在其他任何地方使用,那么 extra 括号的目的是什么?
  • 文档 perlre 不鼓励使用 \1,因为它可能导致意外结果。
  • 语法是$new_string = $old_string =~ s/foo/bar/gr =~ s/blah/baz/gr

标签: regex perl substitution


【解决方案1】:

foreach 循环可用作主题化器。

for ($thisGrid) {
   s/\x0A/\x0D/g;
   s/(?:<ACROSS PUZZLE>.+<GRID>\r\t)([A-Z\.]{15,})(?:\r\t.+)/$1/g; 
}

否则需要使用/r返回修改后的字符串。

$thisGrid =
   $thisGrid
   =~ s/\x0A/\x0D/gr
   =~ s/(?:<ACROSS PUZZLE>.+<GRID>\r\t)([A-Z\.]{15,})(?:\r\t.+)/$1/gr;

你可以把它们串起来

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-14
    • 1970-01-01
    • 2016-10-19
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 2016-09-17
    • 1970-01-01
    相关资源
    最近更新 更多