【问题标题】:perl regex remove anything between pairs of quotesperl 正则表达式删除引号对之间的任何内容
【发布时间】:2014-03-25 03:59:21
【问题描述】:

我有一个字符串,我想删除出现在一对引号之间的任何内容,并将其替换为两个引号。现在我有:

$string =~ s/'.*?'/''/g;

但是,这并不包括字符串中有引号的情况,例如:

$string = "'This is Joe\'s car'";

我希望这个是"''",但实际上最终是"''s car'"

无论如何要删除最外层引号之间的所有内容吗?谢谢!

【问题讨论】:

  • 这不是一项简单的任务。如果字符串中有\\'s 怎么办? \\\'s呢?

标签: regex perl quotes


【解决方案1】:

您通过使正则表达式不贪婪来要求它。说:

$string =~ s/'.*'/''/g;

应该会产生预期的结果。

【讨论】:

  • 但是如果我的字符串可以有多对引用项怎么办?对不起,我想我应该在我的问题中提到这一点。
【解决方案2】:

如前所述,这不是一项简单的任务。除非字符串中有明确的黑斜线来表明引号不应该是平衡对的一部分,否则将没有直接的方法来确定平衡对的位置。这需要编写使用单引号背后的英语语言规则来执行此操作,即使这样也可能存在边缘情况。

一种可能更接近的方法是,如果您使用否定前瞻和后向断言来要求起始引号前面不能有单词字符,并且结束引号后面不能有一个字符。然而,即使这个要求在复数所有格上也会失败,如以下脚本中的最后一个示例所示:

use strict;
use warnings;

while (<DATA>) {
    chomp(my $src = $_);
    chomp(my $test = <DATA>);

    $src =~ s/(?<!\w)'(.*?)'(?!\w)/'<$1>'/g;

    print ($src eq $test ? 'matches  - ' : 'no match - ');
    print $src, "\n";
}


__DATA__
This is just a normal sentence.
This is just a normal sentence.
'This is Joe's car'
'<This is Joe's car>'
She said, "He said, 'Hurry up.'"
She said, "He said, '<Hurry up.>'"
This is 'special.'  That is also 'special.'
This is '<special.>'  That is also '<special.>'
'These are players' cars'
'<These are players' cars>'

【讨论】:

    【解决方案3】:

    你可以试试这个正则表达式:

    $string =~ s/'.*?(?<!\\)'/''/g;
    

    但是这不适用于输入hey 'joe \'car

    【讨论】:

      【解决方案4】:

      您可以尝试使用内置模块Text::Balanced 及其extract_delimited() 功能。在列表上下文中,它返回引号、前缀和提醒之间的文本,因此您可以检查它们并删除这些部分以跳过:

      #!/usr/bin/env perl
      
      use warnings;
      use strict;
      use Text::Balanced qw<extract_delimited>;
      
      my $result;
      
      my $string = "Before quotes 'This is Joe\\'s car' After quotes 'Last content' End";
      
      while ( my @r = extract_delimited($string, q|'|, q|[^']*|) ) { 
          $result .= $r[-1] || ''; 
          if ( ! defined $r[0] ) { 
              $result .= $r[1];
              last 
          }   
          else {
              $result .= "''";
          }   
          $string = $r[1];
      }
      
      printf qq|%s\n|, $result;
      

      请注意,我使用双反斜杠来转义单引号,因为perl 在处理之前会自行转义所有单引号。另请注意,开头的转义单引号,例如:

      my $string = "Before \\'quotes 'This is Joe\\'s car';
      

      也不行。我知道这很奇怪,但它可以在大多数简单的情况下工作。试试看吧。

      像这样运行测试:

      perl script.pl
      

      产生:

      Before quotes '' After quotes '' End
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-03
        • 2014-02-04
        • 1970-01-01
        • 1970-01-01
        • 2013-05-20
        • 1970-01-01
        相关资源
        最近更新 更多