在Perl中,如何删除不在双引号“”内的所有空格?

时间:2012-04-20 14:42:00

标签: regex perl

我想要提出一些正则表达式,它会删除字符串中的所有空格字符,只要它不在双引号(“)内。

示例字符串:

带有“引号中的文字”

的字符串

结果:

somestringwith“引号中的文字”

到目前为止,我已经想到了这样的事情:

    $str =~ /"[^"]+"|/g;

但它似乎没有给出预期的结果。

老实说,我非常擅长perl而且没有太多的正则表达式经验。因此,如果有人愿意回答,也愿意提供一些有关为什么以及如何做到这一点的洞察力!

谢谢!

修改

字符串不包含转义的“

实际上应该总是这样格式化:

Some.String =“Some Value”

结果将是

Some.String =“Some Value”

6 个答案:

答案 0 :(得分:5)

这是一种使用split分隔引用字符串的技术。它依赖于您的数据是一致的,并且不适用于松散的引号。

use strict;
use warnings;

my @line = split /("[^"]*")/;
for (@line) {
    unless (/^"/) {
        s/[ \t]+//g;
    }
}
print @line;  # line is altered 

基本上,您将字符串拆分以隔离引用的字符串。完成后,对所有其他字符串执行替换。由于数组元素在循环中有别名,因此在实际数组上执行替换。

您可以像这样运行此脚本:

perl -n script.pl inputfile

查看输出。或

perl -n -i.bak script.pl inputfile

inputfile上进行就地编辑,同时在inputfile.bak保存备份。

话虽如此,我不确定你的编辑意味着什么。你想改变吗

Some.String = "Some Value"

Some.String="Some Value"

答案 1 :(得分:3)

Text::ParseWords是为此量身定制的:

#!/usr/bin/env perl

use strict;
use warnings;
use Text::ParseWords;

my @strings = (
    q{This.string = "Hello World"},
    q{That " string " and "another   shoutout to my   bytes"},
);

for my $s ( @strings ) {
    my @words = quotewords '\s+', 1, $s;
    print join('', @words), "\n";
}

输出:

This.string="Hello World"
That" string "and"another   shoutout to my   bytes"

使用Text::ParseWords表示如果您必须处理带有转义引号的带引号的字符串,您就可以了; - )

此外,这听起来像你有一个类型的配置文件,你正在尝试解析它。如果是这种情况,可能会有更好的解决方案。

答案 2 :(得分:1)

我建议您使用split删除引用的子字符串,然后在从中间文本中删除空格后将其与join重新组合。

请注意,如果用于split的正则表达式包含捕获,则捕获的值也将包含在返回的列表中。

以下是一些示例代码。

use strict;
use warnings;

my $source = <<END;
Some.String = "Some Value";
Other.String = "Other Value";
Last.String = "Last Value";
END

print join '', map {s/\s+// unless /"/; $_; } split /("[^"]*")/, $source;

<强>输出

Some.String= "Some Value";Other.String = "Other Value";Last.String = "Last Value";

答案 3 :(得分:0)

我只需通过char遍历字符串char。这样你也可以处理转义字符串(只需添加一个isEscaped变量)。

my $text='lala "some thing with quotes " lala ... ';
my $quoteOpen = 0;
my $out;

foreach $char(split//,$text) {
  if ($char eq "\"" && $quoteOpen==0) {
    $quoteOpen = 1;
    $out .= $char;
  } elsif ($char eq "\"" && $quoteOpen==1) {
    $quoteOpen = 0;
    $out .= $char;
  } elsif ($char =~ /\s/ && $quoteOpen==1) {
    $out .= $char;
  } elsif ($char !~ /\s/) {
    $out .= $char;
  }
}

print "$out\n";

答案 4 :(得分:0)

拆分双引号,仅从偶数字段(即引号中的字段)中删除空格:

sub remove_spaces {
    my $string = shift;
    my @fields = split /"/, $string . ' '; # trailing space needed to keep final " in output
    my $flag = 1;
    return join '"', map { s/ +//g if $flag; $flag = ! $flag; $_} @fields;
}

答案 5 :(得分:0)

可以使用正则表达式完成:

s/([^ ]*|\"[^\"]*\") */$1/g

请注意,这不会处理引号内的任何类型的转义。