兩個重要問題的答案將影響你是否甚至需要使用正則表達式來匹配不同的數字格式,或者如果你可以做一些簡單得多:
- 你確定你的行只包含數字還是還包含其他數據(或者可能某些行根本沒有數字,只有其他數據)?
- 您是否確定所有數字都至少被一個空格相互隔開和/或其他數據?如果不是,他們怎麼分開? (例如,從
portsnap fetch
輸出產生大量的數字像這樣3690 .... 3700 ....用小數點和所有沒有空格用來分隔它們。
如果你的行只包含數字並沒有其他的數據和數字之間用空格隔開,那麼你甚至不需要檢查結果是否數字,但只開行拆分:
my @numbers = split /\s+/;
如果你不知道你的行包含數字,但你確定每個數字與其他數字或其他數據之間至少有一個空格,那麼下一行代碼就是一個qui利用聰明的方式讓Perl自己識別所有不同的合法數字格式,這是一種很好的提取數字的好方法。(假定您不想將其他數據值轉換爲NaN
。)@numbers
中的結果將正確識別當前輸入行中的所有數字。
my @numbers = grep { 1*$_ eq $_ } m/(\S*\d\S*)/g;
# we could do simply a split, but this is more efficient because when
# non-numeric data is present, it will only perform the number
# validation on data pieces that actually do contain at least one digit
您可以確定是否至少有一個數字是目前通過檢查表達@numbers > 1
的真值,如果正好四個存在使用條件@numbers == 4
等
如果你的號碼顛簸例如5.17e + 7-4.0e-1,那麼你將會遇到更困難的時間。這是唯一一次你需要複雜的正則表達式。
注意:更新的代碼更快/更好。注意2:由於存儲undef的值時map的工作方式的細微之處,最高位答案有一個問題。當使用該程序從第一行數據(如HTTP日誌文件)中提取數字時,可以通過該程序的輸出來說明。輸出看起來是正確的,但該陣列實際上有許多空的元素,並且如預期那樣找不到存儲在$numbers[0]
中的第一個數字。事實上,這是完整的輸出:
$ head -1 http | perl prog1.pl
Use of uninitialized value $numbers[0] in join or string at prog1.pl line 8, <> line 1.
Use of uninitialized value $numbers[1] in join or string at prog1.pl line 8, <> line 1.
Use of uninitialized value $numbers[2] in join or string at prog1.pl line 8, <> line 1.
Use of uninitialized value $numbers[3] in join or string at prog1.pl line 8, <> line 1.
Use of uninitialized value $numbers[4] in join or string at prog1.pl line 8, <> line 1.
Use of uninitialized value $numbers[5] in join or string at prog1.pl line 8, <> line 1.
Use of uninitialized value $numbers[6] in join or string at prog1.pl line 8, <> line 1.
Use of uninitialized value $numbers[7] in join or string at prog1.pl line 8, <> line 1.
Use of uninitialized value $numbers[10] in join or string at prog1.pl line 8, <> line 1.
Use of uninitialized value $numbers[11] in join or string at prog1.pl line 8, <> line 1.
Use of uninitialized value $numbers[12] in join or string at prog1.pl line 8, <> line 1.
Use of uninitialized value $numbers[13] in join or string at prog1.pl line 8, <> line 1.
Use of uninitialized value $numbers[14] in join or string at prog1.pl line 8, <> line 1.
Use of uninitialized value $numbers[15] in join or string at prog1.pl line 8, <> line 1.
Use of uninitialized value $numbers[16] in join or string at prog1.pl line 8, <> line 1.
200 2206
(請注意這些數字的壓痕顯示許多空數組元素是如何出現在@numbers
,並已通過空間的實際數字之前連接在一起,當陣列已經轉換爲字符串)
但是,我的解決方案在視覺上和實際數組內容中產生了正確的結果,即$ numbers [0],$ number [1]等實際上是第一個和第二個數據文件行中包含的數字。
while (<>) {
my @numbers = m/(\S*\d\S*)/g;
@numbers = grep { $_ eq 1*$_ } @numbers;
print "@numbers\n";
}
$ head -1 http | perl prog2.pl
此外,使用慢庫函數使得較慢的另一溶液運行50%。在10,000行數據上運行程序時,輸出是相同的。
HTTP://計算器。COM /問題/ 638565 /解析,科學的表示法,合理 – 2013-06-20 06:16:37
哦如何在4號分開嗎?你可能分裂和遍歷它們 – 2013-06-20 06:18:59
你的意思是括號'()'當你說括號(這是'[]')?反正它是不是「必要的」,就可以使括號非捕獲詳細的[羅希特的答案](http://stackoverflow.com/a/17206530/1743811)。 – doubleDown