Perl Regex删除连字符但忽略特定连字符

时间:2016-07-16 16:52:07

标签: regex perl strip

我有一个perl正则表达式,它将连字符转换为空格,例如: -

$('#clickMe').click(function(){
    $('#yourDiv').load('footer_data.php');
});

我需要修改它以忽略特定的带连字符的短语,而不是替换连字符,例如在这样的字符串中:

$string =~ s/-/ /g;

我希望不要替换dvi-d和dvi-i中的连字符,所以它显示为:

"use-either-dvi-d-or-dvi-i"

我尝试了各种负面的前瞻性比赛但是失败了。

4 个答案:

答案 0 :(得分:4)

您可以将此PCRE正则表达式与动词(*SKIP)(*F)一起使用,以跳过匹配中的某些字词:

dvi-[id](*SKIP)(*F)|-

RegEx Demo

由于使用了dvi-i,我们会跳过单词dvi-d(*SKIP)(*F)进行拆分。

代码:

$string =~ s/dvi-[id](*SKIP)(*F)|-/ /g;

Perl Code Demo

还有备用外观解决方案

/(?<!dvi)-|-(?![di])/

这基本上意味着匹配连字符如果前面没有dvi或者如果后面没有di,那么请确保在-之后不匹配我们在LHS上有dvi,在RHS上有[di]

Perl代码:

$string =~ s/(?<!dvi)-|-(?![di])/ /g;

Perl Code Demo 2

答案 1 :(得分:1)

$string =~ s/(?<!dvi)-(?![id])|(?<=dvi)-(?![id])|(?<!dvi)-(?=[id])/ /g;

仅使用(?<!dvi)-(?![id])时,您还会排除dvi-xx-i,其中x可以是任何字符。

答案 2 :(得分:0)

你不太可能得到一个简单而直接的正则表达式解决方案。但是,您可以尝试以下方法:

#!/usr/bin/env perl

use strict;
use warnings;

my %whitelist = map { $_ => 1 } qw( dvi-d dvi-i );

my $string = 'use-either-dvi-d-or-dvi-i';

while ( $string =~ m{ ( [^-]+ ) ( - ) ( [^-]+ ) }gx ) {
    my $segment = substr($string, $-[0], $+[0] - $-[0]);
    unless ( $whitelist{ $segment } ) {
        substr( $string, $-[2], 1, ' ');
    }
    pos( $string ) = $-[ 3 ];
}

print $string, "\n";

@-数组包含匹配组的起始偏移量,@+数组包含结束偏移量。在这两种情况下,元素0都指的是整个匹配。

我不得不求助于because of how \G works

  

另请注意s///将拒绝覆盖已替换的部分替换;例如,这将在第一次迭代后停止,而不是通过字符串向后迭代:

   $_ = "123456789";
   pos = 6;
   s/.(?=.\G)/X/g;
   print;     # prints 1234X6789, not XXXXX6789

也许@tchrist可以弄清楚如何根据自己的意愿弯曲各种断言。

答案 3 :(得分:-2)

我们可以使用负面预测负面观察

来忽略特定字词

示例:

(?!pattern)
is a negative look-ahead assertion

在你的情况下,模式是

$string =~ s/(?<!dvi)-(?<![id])/ /g;

输出:

use either dvi-d or dvi-i

参考:http://www.perlmonks.org/?node_id=518444

希望这会对你有所帮助。