正则表达式和多个多字符分隔符

时间:2020-03-06 14:23:44  来源:igfitidea点击:

假设我们具有以下字符串:

white sand, tall waves, warm sun

编写与分隔符匹配的正则表达式很容易,Java String.split()方法可以使用该正则表达式为我们提供一个包含标记"白沙","高浪"和"温暖的阳光"的数组:

\s*,\s*

现在说你有这个字符串:

white sand and tall waves and warm sun

再次,分割令牌的正则表达式很容易(确保我们不会在单词" sand"内得到" and"):

\s+and\s+

现在,考虑以下字符串:

white sand, tall waves and warm sun

是否可以编写与分隔符正确匹配的正则表达式,从而允许我们将字符串拆分为与前两种情况相同的标记?或者,是否可以编写一个与令牌本身匹配并省略定界符的正则表达式? (逗号两侧或者" and"一词的任何空白都应视为定界符的一部分。)

编辑:正如注释中指出的那样,正确答案应该在输入字符串的开头或者结尾牢固地处理定界符。理想的答案应该能够采用",","白色沙滩,高大的波浪和温暖的阳光"之类的字符串,并提供以下确切的三个标记:

[ "white sand", "tall waves", "warm sun" ]

...在任何令牌的开头或者结尾都没有多余的空令牌或者多余的空格。

编辑:已经指出,使用String.split()不可避免地会产生多余的空令牌,因此已将其作为"完美"正则表达式的标准删除。

感谢大家的回应!我试图确保我投票赞成所有提供可使用的正则表达式的人,而这些人实际上并不是重复的。 Dan的答案是最可靠的(它甚至可以处理",白色的沙子,高大的波浪和温暖的阳光",并且"合理地在" waves"之后加上奇数逗号),因此我将他标记为可接受的答案。 nsayer提供的正则表达式紧随其后。

解决方案

这应该同时捕获"和"或者","

(?:\sand|,)\s

是的,这就是regexp的用途:

\s*(?:and|,)\s*

的|定义替代项,()组选择器和:?确保正则表达式引擎不会尝试保留()之间的值。

编辑:避免沙坑(感谢通知):

\s*(?:[^s]and|,)\s*

问题所在

\s*(,|(and))\s*

是它会不适当地分裂"沙子"。

问题所在

\s+(,|(and))\s+

它需要在逗号周围加空格。

正确的答案可能必须是

(\s*,\s*)|(\s+and\s+)

我将通过建议很多语言都具有一个" split"运算符来返还由定界符包围的字符串的概念,以作弊。请参阅Java String.split()函数。

这行得通吗?

\s*(,|\s+and)\s+

(?:(?<!s)and\s+|\,\s+)

可能会工作

没有测试的方法,但是拿出了正确的空间匹配器。

这应该非常有弹性,并且可以在字符串末尾处理诸如定界符之类的东西(例如," foo和bar和")

\s*(?:\band\b|,)\s*

可能是:

((\ s *,\ s *)|(\ s +和\ s +))

我不是Java程序员,所以我不确定java regex是否允许"?"