假设您有以下字符串:
white sand, tall waves, warm sun
编写一个与分隔符匹配的正则表达式很容易,Java String.split()方法可以使用它来为你提供一个包含标记“white sand”,“tall waves”和“warm sun”的数组:
\s*,\s*
现在说你有这个字符串:
white sand and tall waves and warm sun
同样,分割令牌的正则表达式很容易(确保你没有在“沙子”这个词中得到“和”):
\s+and\s+
现在,考虑一下这个字符串:
white sand, tall waves and warm sun
是否可以正确编写与正确分隔符匹配的正则表达式,允许您将字符串拆分为与前两种情况相同的标记?或者,可以编写一个与令牌本身匹配的正则表达式并省略分隔符吗? (逗号两边的任何数量的空格或“and”一词都应被视为分隔符的一部分。)
编辑:正如评论中指出的那样,正确答案应该在输入字符串的开头或结尾处有效地处理分隔符。 理想的答案应该能够像“白沙,高浪和温暖的阳光”这样的字符串,并提供这三个令牌:
[ "white sand", "tall waves", "warm sun" ]
...在任何令牌的开头或结尾都没有额外的空标记或额外的空格。
编辑:有人指出使用String.split()是不可避免的额外空标记,所以它已被删除作为“完美”正则表达式的标准。
感谢大家的回复!我试图确保我对所有贡献了可行的正则表达式的人进行了投票,而这些正则表达式本质上并不重复。丹的答案是最强大的(它甚至处理“,白色的沙子,高大的波浪和温暖的阳光”,合理地说,在“波浪”这个词之后用奇怪的逗号放置),所以我将他标记为已接受的答案。 nsayer提供的正则表达式紧随其后。
答案 0 :(得分:5)
这应该是非常有弹性的,并且在字符串末尾处理分隔符之类的东西(例如“foo and bar and”)
\s*(?:\band\b|,)\s*
答案 1 :(得分:2)
这应该同时包含'和'或','
(?:\sand|,)\s
答案 2 :(得分:2)
的问题
\s*(,|(and))\s*
是它会不恰当地分裂“沙子”。
的问题
\s+(,|(and))\s+
是逗号周围需要空格。
正确答案可能必须是
(\s*,\s*)|(\s+and\s+)
我会通过建议许多语言都有一个“拆分”操作符来完成你想要的正则表达式,当正则表达式指定分隔符本身的形式时,我会稍微讨论返回由分隔符包围的字符串的概念。请参阅Java String.split()函数。
答案 3 :(得分:2)
这会有用吗?
\s*(,|\s+and)\s+
答案 4 :(得分:1)
是的,这正是regexp的用途:
\s*(?:and|,)\s*
|定义备选方案,()将选择器和组分组:确保regexp引擎不会尝试保留()之间的值。
编辑:避免陷阱(感谢通知):
\s*(?:[^s]and|,)\s*
答案 5 :(得分:0)
(?:(?<!s)and\s+|\,\s+)
可能会工作
没有办法测试它,但是拿出了空间匹配器。
答案 6 :(得分:0)
也许:
((\ S *,\ S *)|(\ S +和\ S +))
我不是java程序员,所以我不确定java正则表达式是否允许'?'