2012-03-16 74 views
-7

如果我有如何打印字符串的開頭?

$t = '20110512102331'; 

,只希望前4個字符從$t

我該怎麼做?

+13

你問了很多Perl問題,通常都是非常基本的東西。您現在還沒有學會自己搜索文檔嗎?爲什麼不? – Konerak 2012-03-16 10:12:42

+2

根據你的歷史,我認爲我的書_Learning Perl_可以提供幫助。 :) – 2012-03-16 21:31:15

回答

2

最簡單:使用substr功能:

my $firstfour = substr($t,0,4); 

另一種方法是使用正則表達式:

my $firstfour = ($t =~ /(.{0,4}).*/s ? $1 : $t); 

,或者更短,通過調用列表環境正則表達式:

my ($firstfour) = $t =~ /(.{0,4})/s; 
+2

'm /(。{4})/ ms'更適合「字符串的前四個字符」。當然,弦長小於長度4的情況也是如此。標準假設將返回字符串所具有的字符數量。所以我們可以這樣做:'m /(。{1,4})/ ms'。 – Axeman 2012-03-16 12:10:12

+2

@Axeman:仍然不處理空字符串的情況,這會使$ firstfour未定義。另外'/ m'限定符在這裏是不相關的。 '/(。{0,4})/ s'是正確的。 – Borodin 2012-03-16 13:16:22

+0

謝謝Axeman,好點! @Borodin:它取決於當一個字符串爲空時應該發生什麼,但是「只返回一個空字符串」是有道理的。我會更新! – Konerak 2012-03-16 13:50:59

6

通過使用這樣的substr功能 -

my $t = "20110512102331"; 
my $four = substr($t, 0, 4) 
2
$t='20110512102331'; 
print substr($t, 0, 4); 

更多信息請參見perldoc -f substr

3

對於您的特定問題,從字符串中提取似乎是年份,substr意外地起作用,但在這裏確實是錯誤的答案。 「性格」的概念不是我們的「性格」概念。請注意0​​的不同歸一化形式如何產生不同的結果。你可能想前四個字形,您可以用\X匹配(雖然在ASCII一字形和性格產生相同的結果)

use v5.10.1; 
use utf8; 
use strict; 
use warnings; 

use Unicode::Normalize qw(NFD NFC); 

my $string = '20110512102331'; 
say "$string → ", substr $string, 0, 4; 

my $ustring = NFD('résumé'); 
say "NFD $ustring → ", substr $ustring, 0, 4; 

$ustring = NFC('résumé'); 
say "NFC $ustring → ", substr $ustring, 0, 4; 

$ustring = NFD('résumé'); 
say "\\X with NFD $ustring → ", $ustring =~ m/(\X{4})/; 

$ustring = NFC('résumé'); 
say "\\X with NFC $ustring → ", $ustring =~ m/(\X{4})/; 

通知的NFD結果是不同的:

$ perl -C substr.pl 
20110512102331 → 2011 
NFD résumé → rés 
NFC résumé → résu 
\X with NFD résumé → résu 
\X with NFC résumé → résu 

然而, substr確實有一些Unicode的功夫,如果你給它Unicode::GCString字符串:

use v5.10.1; 
use utf8; 
use strict; 
use warnings; 

use Unicode::GCString; 
use Unicode::Normalize qw(NFD); 

my $gcstring = Unicode::GCString->new(NFD('résumé')); 
say "$gcstring → ", $gcstring->substr(0, 4); 

這得到正確的RESU lt:

$ perl -C gcsubstr.pl 
résumé → résu 

但是,所有這些都解決了字符串不止是字符集合。這些字符有特殊的含義,所以你可以使用這個特殊的含義來做正確的事情,而不用考慮字符串操作。該DateTime::Format::Strptime是解析任意日期格式,如果你能描述格式的好辦法:

use v5.10.1; 
use utf8; 
use strict; 
use warnings; 

use DateTime::Format::Strptime; 

my $Strp = DateTime::Format::Strptime->new(
    pattern => '%Y%m%d%H%M%S', 
    ); 
my $Strf = DateTime::Format::Strptime->new(
    pattern => '%Y', 
    ); 

my $dt = $Strp->parse_datetime('20110512102331'); 

my $year = $Strf->format_datetime($dt); 

say "year is $year"; 

你可能也想看看How can I parse dates and convert time zones in Perl?

你決定這樣做,你可以隱藏子程序的實現細節,所以你可以在不破壞程序的其餘部分改變方式不管。