为什么 ++ 变成了 -+-+-+-:string.gsub 的“奇怪”行为

为什么 ++ 变成了 -+-+-+-

我想清除一个字符串中的双操作符号。我应该怎么处理?

String = "++"
print (String ) -- -> ++
String = string.gsub( String, "++", "+")
print (String ) -- -> + ok
String = string.gsub( String, "--", "+")
print (String ) -- -> +++ ?
String = string.gsub( String, "+-", "-")
print (String ) -- -> -+-+-+- ??
String = string.gsub( String, "-+", "-")
print (String ) -- -> -+-+-+- ??? ;-)
点赞
用户501459
用户501459

核心问题在于 gsub 操作的是 _模式_(Lua 的最小正则表达式),而你的字符串包含未转义的 magic 字符。但是,即使知道了这一点,我自己也对你的结果感到惊讶。

如果我们更改替换字符串,就更容易看出 gsub 在做什么:

string.gsub('+',   '--', '|') => |+|
string.gsub('+++', '--', '|') => |+|+|+|
  • 表示“前一个单元的 0 或多个出现”。与 + 不同,它是非贪婪的,尽可能匹配最少的字符。

我刚刚测试了一下,显然“尽可能匹配最少的字符”主要是指 0 个字符。例如,我对此的直觉是:

string.gsub('aaa','a-', '|')

表达式 a- 将匹配每个 a,将它们替换为 '|',结果为 '|||'。实际上,它在每个字符之前和之后的 0 长度间隙上进行匹配,结果为:'|a|a|a|'

事实上,无论我们在 - 之前加上什么单元,它都始终在长度最小的 0 上进行匹配:

string.gsub('aaa','x-', '|') => |a|a|a|
string.gsub('aaa','a-', '|') => |a|a|a|
string.gsub('aaa','?-', '|') => |a|a|a|
string.gsub('aaa','--', '|') => |a|a|a|

你可以看到最后一个是你的情况,解释了你的结果。你的下一个结果是完全一样的:

string.gsub('+++','+-','|') => |+|+|+|

你的最后一个结果更直截了当:

string.gsub('-+-+-+-','-+','|') => |+|+|+|

在这种情况下,你匹配的是“1 个或多个出现次数的单元 -”,因此你只是替换了 - 字符,正如你预期的那样。

2015-07-16 21:40:15