边界模式 |
|
%f
** 是 Lua 模式中之前未记录的功能(有关未记录的原因,请参阅 LuaList:2006-12/msg00536.html)。**%f
** 允许匹配从字符集 **中未找到** 的字符到字符集 **中找到** 的字符的转换。
在功能上,它与 **\b
** 正则表达式转义序列类似,允许“匹配”从一组字符到另一组字符的转换。
让我们考虑一个相当简单的任务:在字符串中查找所有大写字母的单词。
string.gsub ("the QUICK brown fox", "%u+", print) QUICK
看起来不错,找到了一个全大写的单词。但是看看这个
string.gsub ("the QUICK BROwn fox", "%u+", print) QUICK BRO
我们还找到了一个部分大写的单词。
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.
单词后的标点符号现在是捕获字符串的一部分,这是不想要的。
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)
字符串开头和结尾的正确大写字母的单词没有被检测到。
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)
('_'..s..'_'):gsub('%A(%u+)%A', print)
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
我认为上面的例子在 lua lpeg re 中更快且更易读
s = "THE QUICK brOWN FOx JUMPS over" = re.match(s, "(%A* ( {%u^+4 / %l^+4} (%A/!.) / %a+ ) )+") QUICK JUMPS over