2012-03-06 122 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的概念示例 - 更清晰地說明您要做什麼,我應該可以改進它。

相關問題