邊界範例

lua-users home
wiki

The \"frontier\" 符號範例 %f,以前是 Lua 範例中尚未文件化的功能(關於為什麼它未文件化的原因,請參閱 LuaList:2006-12/msg00536.html)。%f 可讓人在從一個字元集不在的字元,變換為字元集的字元時相符。

在功能上,它與正規表示式跳脫序列 \b 類似,讓人可以「相符」從一個字元集變換至另一個字元集。

我們考慮一個相當簡單的任務:在一個字串中找到所有大寫字彙。

首次嘗試:%u+

string.gsub ("the QUICK brown fox", "%u+", print)

QUICK

這樣看起來不錯,找到了全部大寫的字彙。但看看這個

string.gsub ("the QUICK BROwn fox", "%u+", print)

QUICK
BRO

我們也找到一個部分大寫的字彙。


第二次嘗試:%u+%A

string.gsub ("the QUICK BROwn fox", "%u+%A", print)

QUICK

偵測非字母正確定位了非字母正確定位了部分大寫的字彙。但等等!這個呢

string.gsub ("the QUICK brOWN fox", "%u+%A", print)

QUICK 
OWN 

我們還有另一個問題

string.gsub ("the QUICK. brown fox", "%u+%A", print)

QUICK.

這個字彙後的標點符號現在是擷取字串的一部分,這不是我們想要的。

第三次嘗試:%A%u+%A

string.gsub ("the QUICK brOWN FOx jumps", "%A%u+%A", print)

 QUICK

這成功地排除掉兩個部分大寫的字彙,但仍然將標點符號留在其中,像這樣

string.gsub ("the (QUICK) brOWN FOx jumps", "%A%u+%A", print)

(QUICK)

另外,還有一個問題,除了擷取兩旁的非字母。看看這個

string.gsub ("THE (QUICK) brOWN FOx JUMPS", "%A%u+%A", print)

(QUICK)

字串頭尾正確的大寫字彙沒有被偵測出來。

解決方案:邊界範例:%f

string.gsub ("THE (QUICK) brOWN FOx JUMPS", "%f[%a]%u+%f[%A]", print)

THE
QUICK
JUMPS

邊界範例 %f 後接一個字元集,偵測從「不在字元集」到「在字元集」的轉變。來源字串邊界條件是「不在字元集」,因此它也會與要相符的字串開頭的字彙相符。

第二個邊界範例也會與字串的結尾相符,因此我們最後一個字彙也會被擷取。

沒有邊界範例的替代方法

在沒有邊界範例的情況下,人們只能求助於類似這樣的方法

s = "THE (QUICK) brOWN FOx JUMPS"
s = "\0" .. s:gsub("(%A)(%u)", "%1\0%2")
             :gsub("(%u)(%A)", "%1\0%2") .. "\0"
s = s:gsub("%z(%u+)%z", print)


--NickGammon
最好求助於這種方式
('_'..s..'_'):gsub('%A(%u+)%A', print)
--DmitryGaivoronsky

不太對

s = "THE QUICK brOWN FOx JUMPS"
('_'..s..'_'):gsub('%A(%u+)%A', print)
--> THE JUMPS

你可以這樣做

(' '..s..' '):gsub('%A+', '  '):gsub(' (%u+) ', print)
--> THE QUICK JUMPS

或這樣

s:gsub('%a+', ' %1 '):gsub(' (%u+) ', print)
--> THE QUICK JUMPS

此範例可以延伸到更通用的敘述:「找出所有至少有四個字元,而且全部都是小寫或全部都是大寫的字彙」...

s = "THE QUICK brOWN FOx JUMPS over"
s:gsub('%a+', ' %1 ')      -- identify words with ' (%a+) '
                           -- (all following patterns match a subset of this)
 :gsub(' %u+%l+%a* ', '')  -- subtract mixed case words starting with upper
 :gsub(' %l+%u+%a* ', '')  -- subtract mixed case words starting with lower
 :gsub(' %a%a?%a? ', '')   -- subtract words with 1-3 characters
 :gsub(' (%a+) ', print)   -- extract words
--> QUICK JUMPS over
--DavidManura

我覺得上面的範例在 Lua lpeg re 裡更快且更易讀

s = "THE QUICK brOWN FOx JUMPS over"

= re.match(s, "(%A* ( {%u^+4 / %l^+4} (%A/!.) / %a+ ) )+")
QUICK   JUMPS   over
-- Albert Chan

RecentChanges · Preferences
編輯 · 歷史
最後編輯時間 2024 年 1 月 25 日 晚上 8:51 (GMT) (diff)