正则表达式和多个多字符分隔符
假设我们具有以下字符串:
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是否允许"?"