我有一个字符串:
Ayy ***lol* m8\nlol"
我不希望包含空捕获并产生:
["Ayy ", "**", "*", "lol", "*", " m8", "\n", "lol"]
我正在使用此正则表达式分割字符串:
/(?x)(\*\*|\*|\n|[.])/
这将产生:
["Ayy ", "**", "", "*", "lol", "*", " m8", "\n", "lol"]
答案 0 :(得分:5)
这是您的regex的简化版本,与删除空字符串的方法链接在一起-使用String#split
时在此不可避免,因为在'**中间有一个“空结果” *':
string = "Ayy ***lol* m8\nlol"
string.split(/(\*{1,2}|\n|\.)/).reject(&:empty?)
#=> ["Ayy ", "**", "*", "lol", "*", " m8", "\n", "lol"]
与您的模式有一些区别:
(?x)
;这毫无用处。 Extended patterns对于忽略正则表达式中的空格和注释非常有用-您在此处都不会做任何操作。\*\*|\*
可以简化为\*{1,2}
(或根据需要简化为\*\*?
)。[.]
从技术上讲还不错,但是\.
短了一个字符,我认为显示的意图更加清晰。答案 1 :(得分:3)
使用包含捕获组的正则表达式进行拆分时,连续匹配始终会生成空数组项。
使用
而不是使用 matching 方法arr = arr.reject { |c| c.empty? }
或任何其他方法,请参见How do I remove blank elements from an array?
否则,您将必须使用正则表达式 match 匹配子字符串,该正则表达式将首先匹配deilimiters,然后匹配任何不以delimiter文本开头的文本(也就是说,您需要构建{ {3}}):
arr = s.scan(/(?x)\*{2}|[*\n.]|(?:(?!\*{2})[^*\n.])+/)
在这里
(?x)
-一个自由行距/注释修饰符\*{2}
-**
子字符串|
-或[*\n.]
-一个*
,换行符LF或.
|
-或(?:(?!\*{2})[^*\n.])+
-不是+
,LF或*
(.
)的1个或多个([^*\n.]
)字符不会启动{{ 1}}子字符串。答案 2 :(得分:1)
r = /
[ ]+ # match one or more spaces
| # or
(\*) # match one asterisk in capture group 1
[ ]* # match zero or more spaces
(?!\*) # not to be followed by an asterisk (negative lookahead)
| # or
(\n) # match "\n" in capture group 2
/x # free-spacing regex definition mode
str = "Ayy ***lol* m8\nlol"
str.split r
#=> ["Ayy", "**", "*", "lol", "*", "m8", "\n", "lol"]