2014-02-23 45 views
0

我有一個字符串,我想刪除出現在雙引號之間的任何內容,並用兩個引號替換它。現在,我有:perl正則表達式刪除引號對之間的任何東西

$string =~ s/'.*?'/''/g; 

然而,這並不能掩蓋那裏有一個字符串中的引號,如情況:

$string = "'This is Joe\'s car'"; 

我想爲這是"''",但它真的最終是"''s car'"

有反正去除最外面的一對引號之間的一切嗎?謝謝!

+2

這不是一件小事。如果字符串中有'\'s? '\''s'怎麼樣? – aliteralmind

回答

2

你通過使正則表達式非貪婪來要求它。他說:

$string =~ s/'.*'/''/g; 

應該產生預期的效果。

+0

但是如果我的字符串可以有多對引用項目呢?對不起,我想我應該在我的問題中提到這一點。 – srchulo

0

你可以試試這個正則表達式:

$string =~ s/'.*?(?<!\\)'/''/g; 

但是這不會對輸入hey 'joe \'car

0

您可以用內置模塊Text::Balanced及其extract_delimited()功能試運行。在列表上下文返回任何報價,前綴和提醒的文字,這樣你就可以檢查並刪除那些部分跳過:

#!/usr/bin/env perl 

use warnings; 
use strict; 
use Text::Balanced qw<extract_delimited>; 

my $result; 

my $string = "Before quotes 'This is Joe\\'s car' After quotes 'Last content' End"; 

while (my @r = extract_delimited($string, q|'|, q|[^']*|)) { 
    $result .= $r[-1] || ''; 
    if (! defined $r[0]) { 
     $result .= $r[1]; 
     last 
    } 
    else { 
     $result .= "''"; 
    } 
    $string = $r[1]; 
} 

printf qq|%s\n|, $result; 

請注意,我用了一個雙反斜線逃逸單引號,因爲perl在處理它之前,它自己會逃脫所有單引號。另外請注意,在開始處的轉義單引號如:

my $string = "Before \\'quotes 'This is Joe\\'s car'; 

也不起作用。我知道這很奇怪,但它可以在大多數簡單情況下工作。試試吧。

運行,如測試:

perl script.pl 

國債收益率:

Before quotes '' After quotes '' End 
2

正如已經指出,這不是一個簡單的任務。除非字符串中有明確的黑色斜線來表示報價不是平衡線對的一部分,否則將沒有直接的方法來確定平衡線對在哪裏。這需要編制使用單引號的英語語言規則來做到這一點,即使這樣,也可能會出現邊緣情況。

可能更接近的一種方法是,如果您使用了負向前視,並且在斷言之後要求開始引號不要以單詞字符爲前綴,並且結束引號之後不要跟一個。但是,即使這樣的要求也會失敗,如以下腳本的最後一個例子所示:

use strict; 
use warnings; 

while (<DATA>) { 
    chomp(my $src = $_); 
    chomp(my $test = <DATA>); 

    $src =~ s/(?<!\w)'(.*?)'(?!\w)/'<$1>'/g; 

    print ($src eq $test ? 'matches - ' : 'no match - '); 
    print $src, "\n"; 
} 


__DATA__ 
This is just a normal sentence. 
This is just a normal sentence. 
'This is Joe's car' 
'<This is Joe's car>' 
She said, "He said, 'Hurry up.'" 
She said, "He said, '<Hurry up.>'" 
This is 'special.' That is also 'special.' 
This is '<special.>' That is also '<special.>' 
'These are players' cars' 
'<These are players' cars>' 
相關問題