2012-03-06 112 views
3

我以为我有这个想法,但我想找到一个文件中的所有发生,我有一些文本删除两个双引号之间。删除Perl中两个引号之间的文本?

我需要先找到一个匹配,然后从第一个双引号到匹配,然后将所有文本都转到第二个双引号并将其删除。我不想仅在两个双引号之间获取文本,因为它可能不是该文件中我想要删除的内容。

我以前是这样的:

perl -p -i.bak -e s/bar/foo/g bar.xml 

首先做一个查找和替换工作。 然后我去:

perl -p -i.bak -e s/..\/..\/bar\//g bar.xml 

,并已删除了一切吧,但我需要继续一路到第二个双引号,我不知道怎么做,用Perl。

我认为这将是一些正则表达式的混合,但没有我试过的工作。直到条的部分将始终是相同的,但文本将在该点后更改,但是,它始终以我要删除的部分的第二个双引号结束。在那之后将会有文字。

+4

在引号中是否可以有引号('“a 2 \”4 \“piece of wood”'')? – 2012-03-06 18:38:21

+0

你想匹配什么字符串?包括引号。 – TLP 2012-03-06 18:38:54

+0

两个引号之间不会有任何其他引号,只有文本。不幸的是,我不能发布真实的数据,但它会与此类似:“../../../XXX/XX-XXXX-XXX-XXXXXXX-X.XXX” – 2012-03-06 18:44:43

回答

5
s/"[^"]*foo[^"]*"//g 

作品如果没有逃脱的实际报价之间的报价,如果你想删除包含foo带引号的字符串:

"  # Match a quote 
[^"]* # Match any number of characters except quotes 
foo # Match foo 
[^"]* # Match any number of characters except quotes 
"  # Match another quote 
+0

不知何故,*通配符过于贪婪,它改变了整个文件。我是一个perl新手,但这不起作用:perl -p -i.bak -es /“[^”] * foo [^“] *”// g bar.xml – 2012-03-06 18:57:57

+0

@JamesDrinkard你是什么操作系统使用?我注意到你正在离开报价。通常单引号中的代码被引用:'perl -e'code''。 Linux的单引号,Windows的双引号。如果你不加引号,你就会搞砸了。 – TLP 2012-03-06 19:11:02

+0

我正在使用win7 64位版本的ActivePerl for windows的最新版本。使用引号,我仍然会使用垃圾替换文件中的所有文本,例如:ationroursrtitlratorratorsutilrorationroursrsutulisr ... – 2012-03-06 19:16:11

2

有人在问转义引号。这里有一些技巧。您希望忽略像\"这样的转义引号,但不要引用具有转义转义的字符,例如\\"。要忽略第一个,我使用负面的背后。为了不忽略第二个,我暂时将所有\\更改为。如果你有你的数据,选择其他的东西。

use v5.14; 
use utf8; 
use charnames qw(:full); 

my $regex = qr/ 
    (?<!\\) " # a quote not preceded by a \ escape 
    (.*?)  # anything, non greedily 
    (?<!\\) " # a quote not preceded by a \ escape 
    /x; 

while(<DATA>) { 
    # encode the escaped escapes for now 
    s/(?:\\){2}/\N{SMILING CAT FACE WITH OPEN MOUTH}/g; 
    print "$.: ", $_; 

    while(m/$regex/g) { 
     my $match = $1; 
     # decode the escaped escapes 
     $match =~ s/\N{SMILING CAT FACE WITH OPEN MOUTH}/\\\\/g; 
     say "\tfound → $match"; 
     } 
    } 

__DATA__ 
"One group" and "another group" 
This has "words between quotes" and words outside 
This line has "an \" escaped quote" and other stuff 
Start with \" then "quoted" and "quoted again" 
Start with \" then "quoted \" with escape" and \" and "quoted again" 
Start with \" then "quoted \\" with escape" 
Start with \" then \\\\"quoted \\" with escape\\" 

输出是:

1: "One group" and "another group" 
    found → One group 
    found → another group 
2: This has "words between quotes" and words outside 
    found → words between quotes 
3: This line has "an \" escaped quote" and other stuff 
    found → an \" escaped quote 
4: Start with \" then "quoted" and "quoted again" 
    found → quoted 
    found → quoted again 
5: Start with \" then "quoted \" with escape" and \" and "quoted again" 
    found → quoted \" with escape 
    found → quoted again 
6: Start with \" then "quoted " with escape" 
    found → quoted \\ 
7: Start with \" then "quoted " with escape" 
    found → quoted \\ 
0

您输入说,文件是.xml - 所以我要说的话,我通常做的。

使用XML解析器 - 我喜欢XML::Twig,因为我认为这是比较容易得到认真处理开始。 XML::LibXML也不错。

现在,基于您所问的问题 - 它您试图重写XML属性中的文件路径。

所以:

#!/usr/bin/env perl/ 

use strict; 
use warnings; 

use XML::Twig; 

#my $twig = XML::Twig -> parsefile ('test.xml'); 
my $twig = XML::Twig -> parse (\*DATA); 

foreach my $element ($twig -> get_xpath('element[@path]')) { 
    my $path_att = $element -> att('path'); 
    $path_att =~ s,/\.\./\.\./bar/,,g; 
    $element -> set_att('path', $path_att); 
} 

$twig -> set_pretty_print('indented_a'); 
$twig -> print; 
__DATA__ 
<root> 
    <element name="test" path="/path/to/dir/../../bar/some_dir"> 
    </element> 
    <element name="test2" nopath="here" /> 
    <element path="/some_path">content</element> 
</root> 

XML::Twig也相当有效支持parsefile_inplace工作 “SED风格” 修改一个文件。以上是一些示例XML的概念示例 - 更清晰地说明您要做什么,我应该可以改进它。

相关问题