2010-04-17 90 views
5

在Perl中假設我有一個字符串像'hello\tworld\n',和我要的是:如何在Perl字符串中手動插入字符串轉義字符?

'hello world 
' 

也就是說,「你好」,然後字面製表符,那麼「世界」,然後字面換行符。或等價地,"hello\tworld\n"(注意雙引號)。

換句話說,是否有一個函數用於帶有轉義序列的字符串,並返回一個等價的字符串和所有的轉義序列插值?我不想插入變量或其他任何東西,只是轉義序列,如\x,其中x是一個字母。

回答

8

聽起來像一個問題,別人會有solved already。我從來沒有使用模塊,但它看起來很有用:

use String::Escape qw(unbackslash); 
my $s = unbackslash('hello\tworld\n'); 
+0

非常感謝。我發現String :: Interpolate,但是它做了完全不同的事情。 – 2010-04-17 22:26:32

+0

另外,對於在Ubuntu 9.10中使用它的人來說,String :: Escape的版本沒有'unbacklash'。相反,它有'不可打印'。 – 2010-04-17 22:30:01

2

你可以用「EVAL」做到這一點:

my $string = 'hello\tworld\n'; 
my $decoded_string = eval "\"$string\""; 

注意,有依賴於這種方法,如果你沒有輸入字符串的100%控制的安全問題。

編輯:如果您只想插值\ X替換(而不是「什麼的Perl將插在帶引號的字符串」一般情況下),你可以這樣做:

my $string = 'hello\tworld\n'; 
$string =~ s#([^\\A-Za-z_0-9])#\\$1#gs; 
my $decoded_string = eval "\"$string\""; 

這確實差不多了作爲quotemeta的東西 - 但豁免'\'字符逃脫。

EDIT2:這還不是100%安全的,因爲如果最後一個字符是「\」 - 這將「泄漏」過去字符串雖然結束...

個人而言,如果我想是100%安全的我會做一個散列與我具體想要的潛艇和使用正則表達式替換,而不是一個eval的:

my %sub_strings = (
    '\n' => "\n", 
    '\t' => "\t", 
    '\r' => "\r", 
); 

$string =~ s/(\\n|\\t|\\n)/$sub_strings{$1}/gs; 
+0

我可以使用'eval'和'quotemeta'的組合來安全地做到這一點嗎?基本上,'(我的$ interpolated_string = eval(q(「)。quotemeta($ string)。q(」)))=〜s/\\(。)/ \ 1/g'。 – 2010-04-17 21:35:47

+0

不是沒有它也會消除插值。 ;) – Snowhare 2010-04-17 21:45:08

+0

嗯,我只想插入'\ x',其中'x'是任何字母。不是變量或其他東西。 – 2010-04-17 22:27:13