2014-09-04 58 views
3

只使用一個 Perl的替代正則表達式語句(s///),我們怎麼能寫如下:算術計算在Perl替代模式匹配

每一個成功的比賽只包含一個字母字符A..Z字符串。我們需要用匹配字符串替換匹配字符串,該替換將是匹配字符串中每個字符的字符索引(按字母順序)的總和。

注意:對於A,字符索引將是1,對於B,2 ...和Z軸方向將是26

請參見下面的例子:

success match: ABCDMNA 
substitution result: 38 

注:

1 + 2 + 3 + 4 + 13 + 14 + 1 = 38; 

因爲

A = 1, B = 2, C = 3, D = 4, M = 13, N = 14 and A = 1. 
+5

這功課嗎? – 2014-09-04 22:21:31

+0

「評論:......」當然,它實際上總計達38。 – abiessu 2014-09-04 22:23:01

+0

不。實際上,這會幫助我開始理解如何在Perl中使用正則表達式進行算術計算。 – 2014-09-04 22:23:52

回答

3

菊ST split,翻譯和sum

use strict; 
use warnings; 

use List::Util qw(sum); 

my $string = 'ABCDMNA'; 

my $sum = sum map {ord($_) - ord('A') + 1} split //, $string; 

print $sum, "\n"; 

輸出:

38 
2

您可以使用/e改性劑替代?

$s = "ABCDMNA"; 
$s =~ s/(.)/$S += ord($1) - ord "@"; 1 + pos $s == length $s ? $S : ""/ge; 
print "$s\n" 
2

考慮以下情況的匹配:

my $text = "ABCDMNA"; 
my $val = $text ~= s!(\d)*([A-Z])!($1+ord($2)-ord('A')+1)!gr; 

(無需測試它...)這應該反覆通過串去,在與它的序號值一次更換一個字符添加到已經放在開頭的當前總和。一旦沒有更多字符,副本(/r)將被放置在$val中,該副本應包含翻譯後的值。

+1

這是一個不錯的努力,雖然這不起作用。您需要一種重置比賽位置的方法。我做了'perl -ple'1而s /(\ d *)([AZ])/ $ 1 + ord($ 2)-64/e''這將重置正則表達式匹配到每個新匹配的開始,直到所有字母被消耗。 – TLP 2014-09-04 22:59:21

+0

嗯......我想'/ g'會繼續像這樣重複,哦,我很好 – abiessu 2014-09-05 00:09:12

+0

我會保留這個答案來補充你的@TLP。 – abiessu 2014-09-05 00:16:50

0

或短替代:

echo ABCDMNA | perl -nlE 'm/(.)(?{$s+=-64+ord$1})(?!)/;say$s' 

或可讀

$s = "ABCDMNA"; 
$s =~ m/(.)(?{ $sum += ord($1) - ord('A')+1 })(?!)/; 
print "$sum\n"; 

打印

38 

說明:

  • 試圖匹配any character什麼不能跟隨「空正則表達式」。 /.(?!)/
  • 因爲一個空的正則表達式匹配所有的東西,所以「沒有任何東西跟隨」,這是不正確的。
  • 因此,正則表達式引擎移動到下一個字符,並再次嘗試匹配
  • 這是重複的,直到耗盡整個字符串。
  • 因爲我們想捕捉人物,使用捕獲組/(.)(?!)/
  • (?{...})運行Perl代碼,當正則表達式耗盡什麼總結存儲在$1
  • 捕獲的字符的值(和失敗),最後say $s從perlre

    打印總和

的值(?{代碼})

該零寬度斷言執行任何嵌入式Perl代碼。它總是 成功,並且其返回值設置爲$^R。

警告:安全地使用此功能要求您瞭解其限制條件 。由於正則表達式引擎中的未來 優化的影響,執行的帶有副作用的代碼可能不會執行 從版本到版本的完全相同。欲瞭解更多信息,請參閱 嵌入式代碼執行頻率。

4

我會張貼此作爲一個答案,我想,雖然能想出這個主意的功勞應該去abiessuhis answer提出的想法。

perl -ple'1 while s/(\d*)([A-Z])/$1+ord($2)-64/e' 

因爲這顯然是功課和/或學術興趣,我將在後擾流器標籤的說明。

- 我們匹配一個可選號碼(\d*),後跟一個字母([A-Z])。這個數字是運行總和,這個字母就是我們需要增加的總和。
- 通過使用/e修飾符,我們可以執行數學運算,即將捕獲的數字添加到捕獲的字母的ord()值減去64.將返回並插入總和,而不是數字和字母。
- 我們使用while環進行沖洗並重復,直到所有字母被替換,剩下的只是一個數字。我們使用while循環而不是/g修飾符將匹配重置爲字符串的開頭。

+2

擾流器標籤+1!聰明! – 2014-09-05 00:23:39