【问题标题】:Perl regular expression to match string in quotes while ignoring escaped quotesPerl正则表达式匹配引号中的字符串,同时忽略转义引号
【发布时间】:2015-06-04 20:51:59
【问题描述】:

我需要帮助设计一个 Perl 正则表达式来匹配单引号内的字符串,其中可能存在转义的单引号。

比如输入文本:

'SELECT * FROM TABLE WHERE COLUMN = \'text\''

将匹配外部单引号内的所有内容,包括列文本周围的转义引号。即:

SELECT * FROM TABLE WHERE COLUMN = \'text\'

我试过这个:

/\s*'([^'|[^\\']]*)'\s*/

但是那个匹配组根本没有匹配任何东西。任何帮助将不胜感激。

【问题讨论】:

  • 你可以试试这个:regexper.com
  • 请将您遇到问题的代码添加到问题中。我相信没有真正的反斜杠,只有's。

标签: regex perl


【解决方案1】:

您可以使用以下正则表达式:

/'((?:\\.|[^'\\])*)'/

或产生更好性能的展开版本:

/'([^'\\]*(?:\\.[^'\\]*)*)'/

Demo 1Demo 2

正则表达式解释:

  • ' - 初始单引号
  • ((?:\\.|[^'\\])*) - 捕获组包括
    • (?:\\.|[^'\\])* - 除了 '\ 或转义实体之外的 0 个或多个字符
  • ' - 最后的单引号

演示:

my $str = "'SELECT * FROM TABLE WHERE COLUMN = \\'text\\'' "; 
 print "$str\n";
if ( $str =~ /'([^'\\]*(?:\\.[^'\\]*)*)'/ ) {
    print "$1\n";
}

demo program 的输出:

SELECT * FROM TABLE WHERE COLUMN = \'text\'

【讨论】:

  • 很好的解决方案。但请问,?: 语法是什么意思?
  • ?: 将一个组标记为非捕获组,即我们将无法使用对它的反向引用。当我们不想跟踪捕获的组时非常方便。实际上,如果我们“展开”它,正则表达式可以得到改进。我加了。
  • 我看到你手动转义了转义字符。当手动将字符串分配给代码中的变量时,有没有办法能够捕获转义?
  • 如果您询问我使用的 $str 值,我确实将“\”转义为文字。我认为您的输入字符串包含这样的单引号,这些单引号前面是文字“\”。如果您在 Perl 字符串文字中询问“\'”,它们将被插入文字 ',因此您不会在输出中看到它们。您需要使用另一段代码在它们之前手动添加一个斜杠。
  • @Hussain:我更新了我的答案,我想强调'([^'\\]*(?:\\.[^'\\]*)*)'((?:\\.|[^'\\])*) 相同。我解释了后者。
【解决方案2】:

我认为您正在寻找的正则表达式是这样的:

/\s*'(([^']|[\\'])*)'\s*/

【讨论】:

    【解决方案3】:
    #!/usr/bin/perl
    
    $string = "'SELECT * FROM TABLE WHERE COLUMN = \'text\''";
    
    $string =~ /^'(.*)'$/;
    $string = $1 if $1;
    
    print "$string\n";
    

    输出:

    SELECT * FROM TABLE WHERE COLUMN = 'text'
    

    当输入来自外部源时(即没有在代码本身中作为字符串 var 手动插入),上述正则表达式有效:

    open my $fh, '<', 'in.txt';
    
    $string = <$fh>;
    
    $string =~ /^'(.*)'$/;
    $string = $1 if $1;
    
    print "$string\n";
    

    输入文件:

    $ cat in.txt 
    'SELECT * FROM TABLE WHERE COLUMN = \'text\''
    

    输出:

    SELECT * FROM TABLE WHERE COLUMN = \'text\'

    【讨论】:

    • 理想情况下,匹配的文本应包含转义字符。 IE。 SELECT * FROM TABLE WHERE COLUMN = \'text\'
    • 这个字符串是从外部源引入的,而不是手动分配给代码中的字符串 var 吗?如果是这样,它会按您的意愿工作。我已经更新了我的答案作为一个例子。让我知道...如果您在代码中手动分配,我会做更多的测试。
    • 这仅适用于您有一个带前导/尾随单引号的带引号的字符串。如果你有很多,比如说,分隔的,这将失败。
    【解决方案4】:

    如果这只是针对来自已知来源的转储数据,您可以对其进行评估。

    my $str =q{ 'SELECT * FROM TABLE WHERE COLUMN = \'text\'' };
    my $out = eval $str;
    say $out;
    

    【讨论】:

      猜你喜欢
      • 2014-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-25
      • 2011-08-07
      • 2017-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多