将除单引号之间的内容以外的所有内容都小写-perl

时间:2018-11-13 15:59:33

标签: perl

在perl中是否有一种方法可以使用正则表达式替换输入行中的所有文本(单引号内的文本除外(可能不止一个)),我已经使用下面的代码实现了这一点,但想看看是否可以完成使用正则表达式和地图。

while (<>) {
    my $m=0;
    for (split(//)) { 
        if (/'/ and ! $m) {
            $m=1;
            print;
        }
        elsif (/'/ and $m) {
            $m=0;
            print;
        }
        elsif ($m) {
            print;
        }
        else {
            print lc;
        }
    }
} 

**Sample input:**

and (t.TARGET_TYPE='RAC_DATABASE' or (t.TARGET_TYPE='ORACLE_DATABASE' and t.TYPE_QUALIFIER3 != 'racinst'))

**Sample output:**

and (t.target_type='RAC_DATABASE' or (t.target_type='ORACLE_DATABASE' and t.type_qualifier3 != 'racinst'))

3 个答案:

答案 0 :(得分:2)

您可以试一下。所有一个正则表达式。

$str =~ s/(?:^|'[^']*')\K[^']*/lc($&)/ge;

或者,更清洁,更有据可查(这在语义上等同于上述内容)

$str =~ s/
  (?:
    ^     | # Match either the start of the string, or
    '[^']*' # some text in quotes.
  )\K       # Then ignore that part,
            # because we want to leave it be.
  [^']*     # Take the text after it, and
            # lowercase it.
  /lc($&)/gex;

g标志告诉regexp运行所需的次数。 e告诉我们替换部分(在我们的例子中为lc($&))是Perl代码,而不仅仅是文本。 x让我们在其中放置这些注释,以免regexp完全乱码。

答案 1 :(得分:1)

对于这样简单的工作,您不是对regexp玩得太辛苦了吗?

为什么今天不让孩子“分裂”呢?

#!/usr/bin/perl
while (<>)
{
    @F = split "'";
    @F = map { $_ % 2 ? $F[$_] : lc $F[$_] } (0..@F);
    print join "'", @F;
}

以上内容仅供参考。我们经常将后两行合理地合并为:

print join "'", map { $_ % 2 ? $F[$_] : lc $F[$_] } (0..@F);

还是享受更多,使其成为一线? (在bash shell中)在概念上看起来像:

perl -pF/'/ -e 'join "'", map { $_ % 2 ? $F[$_] : lc $F[$_] } (0..@F);' YOUR_FILE

但是,实际上,我们需要尊重shell并做一些逃避(艰苦的)工作:

perl -pF/\'/ -e 'join "'"'"'", map { $_ % 2 ? $F[$_] : lc $F[$_] } (0..@F);' YOUR_FILE

(单引号的单引号必须变为5个字母:'"'"'

如果它对您的工作没有帮助,则可以帮助睡眠。

答案 2 :(得分:0)

Perl单线又一个变种。我使用十六进制\ x27作为单引号

$ cat sql_str.txt
and (t.TARGET_TYPE='RAC_DATABASE' or (t.TARGET_TYPE='ORACLE_DATABASE' and t.TYPE_QUALIFIER3 != 'racinst'))

$ perl -ne ' { @F=split(/\x27/); for my $val (0..$#F) { $F[$val]=lc($F[$val]) if $val%2==0 } ; print join("\x27",@F) } ' sql_str.txt
and (t.target_type='RAC_DATABASE' or (t.target_type='ORACLE_DATABASE' and t.type_qualifier3 != 'racinst'))

$