如何转变这种特殊的正则表达式的激励案例?

时间:2014-04-26 11:11:01

标签: regex perl bash

这段特殊代码:

s/([a-zA-Z0-9]+)/$h{$1} || "[$1]"/eg;

我需要使用-i但它似乎不起作用和bash投诉。

-is/([a-zA-Z0-9]+)/$h{$1} || "[$1]"/eg;

我正在打电话:

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

open my $LOOKUP , "<" , "equivalents.txt";
open my $LIST   , "<" , "input-text.txt";
open my $OUTPUT , ">" , "output.txt";

my %h;

while (<$LOOKUP>) {
    chomp;
    my ($k, $v) = split /\s*=\s*/;
    $h{$k} = $v;
}

while (<$LIST>) {
     -is/([a-zA-Z0-9]+)/$h{$1} || "[$1]"/eg;
    print $OUTPUT $_;
}

这就是我在输入文档中的内容:

this is working good.
THIS IS WORKING GOOD.
This is Working Good.

两个第一行似乎不是第三行:

DHíS íZ W3rKiNG GúD.
DHíS íZ W3rKiNG GúD.
[This] íZ [Working] [Good].

问题是,当在输入中一个单词以大写字母开头时,它无法翻译它。 我试图通过在等效文件中创建两个可能性来解决问题,这意味着:

this = Dhís
THIS = Dhís

但是后来我面临的问题是,某些单词可能在开头或中间或结尾处或字符串中的任何位置包含大写字母,因此在显然我的问题是区分大小写时创建所有这些可能性会很疯狂

我试过了:

-is/([a-zA-Z0-9]+)/$h{$1} || "[$1]"/eg;

但是bash说:

syntax error at 1.pl line 19, near "+)"
Search pattern not terminated at 1.pl line 19.

此外我想问一下,如果我的输入是1gb的txt文件,那么这个脚本是否有用,或者我必须做其他的事情,但主要的问题是敏感案例。

1 个答案:

答案 0 :(得分:3)

替换s/([a-zA-Z0-9]+)/$h{$1} || "[$1]"/eg已经不区分大小写,因为字符类[a-zA-Z0-9]中包含小写和大写ASCII字母。否则,您可以通过在结束分隔符/i之后添加s/([a-zA-Z0-9]+)/$h{$1} || "[$1]"/egi标志来添加不区分大小写。

无论如何,您不是在寻找不区分大小写的正则表达式匹配,而是针对不区分大小写的哈希查找 $h{$1}。最好的解决方案是规范化密钥。使用use feature 'fc'use Unicode::CaseFold 'fc'来获取用于大小写归一化的fc函数(在ASCII范围内,您可以通过lcuc获得相同的效果)

use feature 'fc';   # available since perl 5.16, use Unicode::CaseFold before that

my %h;

while (<$LOOKUP>) {
    chomp;
    my ($k, $v) = split /\s*=\s*/;
    $h{fc $k} = $v;
}

while (<$LIST>) {
    s/([a-zA-Z0-9]+)/$h{fc $1} || "[$1]"/eg;
    print $OUTPUT $_;
}