在Perl中,如何使用正则表达式替换运算符替换子字符串中的非ASCII字符?

时间:2012-06-28 08:25:51

标签: regex perl

如何使用此命令:

perl -pi -e 's/[^[:ascii:]]/#/g' file

仅将偏移量A处的字符更改为每行的偏移量B

2 个答案:

答案 0 :(得分:7)

根据保留,我没有正确理解你的问题,如果抵消A和B是5和10,那么它应该是:

  perl -pi -e 's/(?<=.{5})(?<!.{10})[^[:ascii:]]/#/g' file

说明:

   [^[:ascii:]]  <- the character which is looked for
   (?<=.{5})     <- if at least 5 chars were before (offset 5)
   (?<!.{10})    <- but no more than 10 characters before (offset 10)

构造:

   (?<= ...) and (?<! ...)

被称为正面和负面的lookbehinds ,它们零 - 带有断言。 (您可以谷歌查看,请参阅Look-Around Assertions中的perlre部分)

<小时/> 附录1 您在标题中提到了substr(),我首先忽略了这一点。当然,这也可以起作用:

  perl -pi -e 'substr($_,5,10)=~s/[^[:ascii:]]/#/g' file 

substr EXPR,OFFSET,LENGTH的说明可以是found in perldoc。 这个例子很好地说明了使用substr()作为左值。

<小时/> 附录2 在更新这篇文章时,Grrrr添加了相同的解决方案作为答案,但他先来了一分钟! (所以他应该得到战利品)

此致

RBO

答案 1 :(得分:7)

除了橡胶靴的答案,你可以开始使用子串而不是整个字符串:

perl -pi -e 'substr($_, 5, 5) =~ s/[^[:ascii:]]/#/g' file

举例说明:

perl -e 'print "\xff" x 16' | \
perl -p -e 'substr($_, 5, 5) =~ s/[^[:ascii:]]/#/g' | \
hd

将打印

ff ff ff ff ff 23 23 23  23 23 ff ff ff ff ff ff

在此代码中,第一个偏移量是基于0的,您必须使用长度而不是第二个偏移量,因此它将是 substr($_, A-1, B-A)