正则表达式中的 perl 正则表达式

Posted

技术标签:

【中文标题】正则表达式中的 perl 正则表达式【英文标题】:perl regex within a regex 【发布时间】:2012-06-29 00:14:25 【问题描述】:

在 perl 中有很多次我想在匹配的另一个替换运算符完成后用它自己替换匹配的字符串。例如,我有一个应用程序,我需要在其中查找带引号的字符串并从中删除空格。一种方法是:

while($str =~ s/"([^"])+"//)
   $temp = $1;
   $temp2 = $temp;
   $temp =~ s/ /_/g;
   $str =~ s/$temp2/$temp1/;

这似乎也是可能的:

$str =~ s/"([^"])+"/replace_spaces($1)/gx;
sub replace_spaces()
    $word = shift;
    $word =~ s/ /_/g;
    return $word;

有没有一种纯粹的正则表达式方法,通过某种方式在一个正则表达式中嵌套一个正则表达式?

【问题讨论】:

是的,我知道它在 Programming Perl 的庞大正则表达式一章中讨论过,但我不记得 tomh。 【参考方案1】:

对于手头的具体任务,最好使用Text::ParseWords:

#!/usr/bin/env perl

use strict; use warnings;
use feature 'say';
use Text::ParseWords;

my $input = qThis is "a t e s t " string. "Hello - world  !";
my @words = shellwords $input;

for my $word ( @words ) 
    $word =~ s/ +//g;
    say "'$word'";

另见How can I split a [character]-delimited string except when inside [character]?

【讨论】:

【参考方案2】:

是的,您可以这样做,但在每种情况下,您都需要发明新的正则表达式。 在这种情况下没有灵丹妙药。

您必须使用下划线更改空格,但不能全部更改,只有在引号分隔的子字符串内。您检查的最后一个条件是向前看和向后看断言,但这些检查并不那么容易制定。

例如:

$ perl -pe 's/(?<=")(\S+)\s+(?=.*")/$1_/g;'
a b "c d" e f
a b "c_d" e f

但这个 re 远非完美。这适用于最简单的情况。这不是一个解决方案,它只是一个想法的演示。

【讨论】:

【参考方案3】:

你可以试试:

   $str =~ s"([^"]+)"do(local$_=$1)=~y/ /_/;$_eg;

或者,为了更好的可读性:

   $str =~ s/
             "([^"]+)"     # all inside double quotes to $1
            / do          # start a do block
                 local $_ = $1; # get a copy from $1
                 y| |_|;        # transliterate ' ' to '_'
                 $_             # return string from block
                          # end the do block
            /xeg;

问候

rbo

【讨论】:

以上是关于正则表达式中的 perl 正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

Perl正则表达式引用

Perl教程 - 正则表达式

更改 Perl 中的默认正则表达式行为?

Perl 中的正则表达式组:如何从正则表达式组中捕获与字符串中出现的未知数量/多个/变量匹配的元素到数组中?

Perl正则表达式

我应该使用 \d 还是 [0-9] 来匹配 Perl 正则表达式中的数字?