询问Perl Regexes

时间:2014-07-15 19:40:33

标签: regex perl

这个问题与我昨天问过的问题有关。我是Perl的新手,我仍然掌握着各种各样的东西*。在代码中,我试图用撇号替换右单引号。但是,我不想在单引词上替换正确的单引号。一个例子是:

He said the movie was 'magnificent.' 

以下是我目前正在使用的代码:

#!/usr/bin/perl
use strict;
use warnings;

# Subroutine prototype
sub problem_character();

my $previousPosition=0;
my $currentPosition=0;

#Locates problematic apostrophes and replaces them with properly encoded apostrophes
sub problem_character(){
    while($_[0]=~m/\x{2019}/g){
        $currentPosition=pos($_[0]);
        pos($_[0])=$previousPosition;
        unless(....){
            $_[0]=~s/\x{2019}/\x{0027}/g;
        }
        $previousPosition=$currentPosition;
    }
}

首先,我不确定除非检查,否则我会放入什么。我希望能够检查匹配的右单引号是否是单引词的一部分。此外,在Perl文档中,pos函数是最后一次m//q搜索中断的偏移量。替换搜索是否属于此类别?最后,有没有更简单的方法来编写这种类型的代码?谢谢。

*有没有人知道我能拿到的一本好书,详细解释了Peril?我发现在线资源非常混乱。

1 个答案:

答案 0 :(得分:0)

您发布了以下内容:

He said the movie was 'magnificent.'

但是你说你试图替换那个字符串中不存在的。你真的有这个吗?

He said the movie was ‘magnificent.’

如果是这样,简单的解决方案就是替换前面的不匹配的所有。不过,实施起来有点棘手。

s{
    \G
    (?: [^\x{2018}\x{2019}]++
    |   \x{2018} [^\x{2018}\x{2019}]*+ \x{2019}?+
    )*+
    \K
    \x{2019}
}{'}xg;

更简单(但效率稍低)实施:

$_ = reverse($_);
s/\x{2019}(?![^\x{2018}\x{2019}]*\x{2018})/'/g;
$_ = reverse($_);

顺便说一下,如果需要,您可以在正则表达式模式中实际使用字符。只需确保使用UTF-8对文件进行编码,然后使用use utf8;

告诉Perl
use utf8;  # Source code is encoded using UTF-8.

$_ = reverse($_);
s/’(?![^‘’]*‘)/'/g;
$_ = reverse($_);