Ruby 我可以使用什么正则表达式将字符串拆分为单词,但将圆括号中的短语放在一起?
我想像这样拆分一个字符串:Ruby 我可以使用什么正则表达式将字符串拆分为单词,但将圆括号中的短语放在一起?,ruby,regex,Ruby,Regex,我想像这样拆分一个字符串: my_string = "I want to split this (these should stay together) correctly" 并得出以下结果: ["I", "want", "to", "split", "this", "(these should stay together)", "correctly"] 我试过这个: my_string.split(/(?=[^\(]){1,} (?=[^\)]){1,}/) 但是圆括号内的元素被分开了。
my_string = "I want to split this (these should stay together) correctly"
并得出以下结果:
["I", "want", "to", "split", "this", "(these should stay together)", "correctly"]
我试过这个:
my_string.split(/(?=[^\(]){1,} (?=[^\)]){1,}/)
但是圆括号内的元素被分开了。如何实现此目的?您可以使用此正则表达式使用
split
:
/ +(?![^()]*\))/
i、 e
(?![^()]*\)
是负向前看,这意味着如果空格后跟0个或多个非圆括号字符和右圆括号,则不匹配空格,因此不匹配(…)
拆分
是错误的工具。使用扫描
my_string.scan(/\([^)]*\)|\S+/)
# => ["I", "want", "to", "split", "this", "(these should stay together)", "correctly"]
如果平衡圆括号可以与要组合在一起的其他非空格字符相邻,则您可能需要此圆括号,它通常适用于:
my_string.scan(/(?:\([^)]*\)|\S)+/)
通常,当分隔符可以用简单模式表示时,请使用split
。当内容可以用简单模式表示时,使用scan
可能需要分两步进行,以保持正则表达式的简单性:
my_string.scan(/\([^)]*\)|\S+/)
# => ["I", "want", "to", "split", "this", "(these should stay together)", "correctly"]
first, middle, last = my_string.partition /\(.*\)/
[*first.split, middle, *last.split]
#=> ["I", "want", "to", "split", "this", "(these should stay together)",
# "correctly"]
另一个例子:
first, middle, last = "x (x(x(x)x)x) x".partition /\(.*\)/
[*first.split, middle, *last.split]
#=> ["x", "(x(x(x)x)x)", x"]
但它在这里失败了:
first, middle, last = "x (x)x(x) x".partition /\(.*\)/
[*first.split, middle, *last.split]
#=> [ "x, "(x)x(x)", "x"]
假设需要[“x”,“x”,“x”,“x”,“x”],“x”]
。出于好奇:
my_string.gsub(/\(.+?\)/) { |m| m.gsub ' ', ' ' }.split(/ +/)
尝试将上述代码复制粘贴到IRB中,并继续关注:
#⇒ ["I", "want", "to", "split", "this",
# "(these should stay together)", "correctly"]
:)
NB这是一个玩笑,请不要在生产中使用
正如@sawa所建议的,这是一种逃避,因此,为了使这个答案正确,我们应该将所有内容转换回正常空间:
my_string.gsub(/\(.+?\)/) { |m| m.gsub ' ', ' ' }
.split(/ +/)
.gsub ' ', ' '
是否保证FSM会按照列出的顺序尝试或匹配?mudasobwa是的。顺序很重要。这将在嵌套括号上返回意外(IMHO)结果。@mudasobwa Correct。我认为情况并非如此。使用稍微复杂一点的正则表达式,可以捕获嵌套的括号。我的例子中没有嵌套的括号,所以这是可行的,但是绑定到这个非常具体的示例(即,只能有一个平衡的括号)。但你是对的。分多个步骤执行可以使正则表达式更简单。实际上,使用split
可以捕获分隔符以及中间的子字符串,并使用each_cons(2)
,您可以概括您的答案行以允许任意数量的平衡括号。@sawa,*
贪婪这一事实难道不能解决你的担忧吗?我可能没有领会你的意思。一个有问题字符串的示例?对。您必须使用[^)]
或非贪婪来修复该部分。代码中有一个有问题的字符串是“foo bar(A b)baz(c d)foo”
。我不知道m.gsub'',''
在做什么。但它是有效的。其中一个是制表符还是非ASCII空格?当然可以,但事实上你不应该对这个答案投赞成票。这是欺骗。ASCII-8不可破坏空间,是的。你的方法没有错。认真地你为什么评论不使用它?这是一个非常干净的想法。这个想法可以看作是某种逃避。@sawa那么我至少应该把这些空间转换回去。我将更新答案。您可以使用可见的内容(但在普通文本中很少使用)使其更易于理解。如果字符串是“x((x)x”
,您是否希望[“x”、“((x)”、“x”]
或[“x”、“(,“(x)”、“x”]
?