选项 1
/\b/ 是word boundary,它的宽度为零,因此不会消耗任何字符
'abc+def'.split(/\b/)
# => ["abc", "+", "def"]
'abc*def+eee'.split(/\b/)
# => ["abc", "*", "def", "+", "eee"]
'ab/cd*de+df'.split(/\b/)
# => ["ab", "/", "cd", "*", "de", "+", "df"]
选项 2
如果您的字符串包含其他单词边界字符并且您只想在-、+、* 和/ 上进行拆分,那么您可以使用capture groups。如果使用捕获组,String#split 还将在结果中包含捕获的字符串。 (感谢您指出这一点 @Jordan)(@Cary Swoveland 抱歉,我在进行此编辑时没有看到您的回答)
'abc+def'.split /([+*\/-])/
# => ["abc", "+", "def"]
'abc*def+eee'.split /([+*\/-])/
# => ["abc", "*", "def", "+", "eee"]
'ab/cd*de+df'.split /([+*\/-])/
# => ["ab", "/", "cd", "*", "de", "+", "df"]
选项 3
最后,对于那些使用可能不支持使用捕获组进行字符串拆分的语言的人,您可以使用两个lookarounds。 Lookarounds 也是零宽度匹配,因此它们不会消耗任何字符
'abc+def'.split /(?=[+*\/-])|(?<=[+*\/-])/
# => ["abc", "+", "def"]
'abc*def+eee'.split /(?=[+*\/-])|(?<=[+*\/-])/
# => ["abc", "*", "def", "+", "eee"]
'ab/cd*de+df'.split /(?=[+*\/-])|(?<=[+*\/-])/
# => ["ab", "/", "cd", "*", "de", "+", "df"]
这里的想法是分割前面有一个分隔符的任何字符,或者后面有一个分隔符的任何字符。让我们做一点视觉效果
ab ⍿ / ⍿ cd ⍿ * ⍿ de ⍿ + ⍿ df
小⍿ 符号前面或后面是分隔符之一。所以这就是字符串将被切断的地方。
选项 4
也许您的语言没有字符串split 函数或与正则表达式交互的合理方式。很高兴知道您不必坐下来猜测是否有巧妙的内置程序可以神奇地解决您的问题。几乎总有一种方法可以使用基本说明来解决您的问题
class String
def head
self[0]
end
def tail
self[1..-1]
end
def reduce acc, &f
if empty?
acc
else
tail.reduce yield(acc, head), &f
end
end
def separate chars
res, acc = reduce [[], ''] do |(res, acc), char|
if chars.include? char
[res + [acc, char], '']
else
[res, acc + char]
end
end
res + [acc]
end
end
'abc+def'.separate %w(- + / *)
# => ["abc", "+", "def"]
'abc*def+eee'.separate %w(- + / *)
# => ["abc", "*", "def", "+", "eee"]
'ab/cd*de+df'.separate %w(- + / *)
# => ["ab", "/", "cd", "*", "de", "+", "df"]