代码之家  ›  专栏  ›  技术社区  ›  Robert J. Walker

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

  •  1
  • Robert J. Walker  · 技术社区  · 16 年前

    假设您有以下字符串:

    white sand, tall waves, warm sun
    

    很容易编写一个正则表达式,它将与分隔符匹配,Java字符串.SPLIT()方法可以给你一个数组,其中包含令牌“白沙”、“高波”和“温暖的太阳”:

    \s*,\s*
    

    现在假设你有这个字符串:

    white sand and tall waves and warm sun
    

    同样,分割标记的regex也很容易(确保您不会在单词“sand”内得到“and”):

    \s+and\s+
    

    现在,考虑这个字符串:

    white sand, tall waves and warm sun
    

    是否可以编写一个与分隔符正确匹配的regex,允许您将字符串拆分为与前两种情况相同的标记?或者,是否可以编写一个正则表达式来匹配标记本身并省略分隔符?(逗号或单词“and”两侧的任何数量的空格都应视为分隔符的一部分。)

    编辑:正如注释中所指出的,正确的答案应该在输入字符串的开头或结尾有力地处理分隔符。这个 理想的 答案应该能够取一根类似“白色沙滩,高高的波浪和温暖的阳光”的绳子,并提供这三个确切的标记:

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

    ……没有 额外的空令牌或 在任何令牌的开始或结束处都有额外的空白。

    edit:有人指出,string.split()不可避免会有多余的空标记,因此这已被作为“完美”regex的标准删除。


    感谢大家的回答!我试着确保我对每个贡献了一个可操作的regex的人都投了反对票,而这个regex本质上并不是重复的。丹的回答是最有力的(它甚至能处理),白沙,巨浪,温暖的阳光和“合理地,在单词“waves”后面加上这个奇怪的逗号”,所以我把他的答案标为公认的答案。nsayer提供的regex是一个非常接近的秒。

    7 回复  |  直到 16 年前
        1
  •  5
  •   Dan Aditi    16 年前

    这应该很有弹性,可以处理字符串末尾的分隔符之类的东西(例如foo、bar和)。

    \s*(?:\band\b|,)\s*
    
        2
  •  2
  •   Shinhan    16 年前

    这行吗?

    \s*(,|\s+and)\s+
    
        3
  •  2
  •   UnkwnTech    16 年前

    这应同时捕获“和”或“,”

    (?:\sand|,)\s
    
        4
  •  2
  •   nsayer    16 年前

    问题在于

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

    它会不适当地分裂出“沙子”。

    问题在于

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

    它需要逗号周围的空格。

    正确的答案可能是

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

    我将在返回由分隔符包围的字符串的概念上做一点小小的欺骗,建议许多语言都有一个“split”操作符,当regex指定分隔符本身的形式时,该操作符会完全满足您的需要。参见JavaStry.SPLIT()函数。

        5
  •  1
  •   Bite code    16 年前

    是的,这就是regexp的用途:

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

    定义备选方案,()对选择器和:?确保regexp引擎不会尝试保留()之间的值。

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

    \s*(?:[^s]and|,)\s*
    
        6
  •  0
  •   Quintin Robinson    16 年前
    (?:(?<!s)and\s+|\,\s+)
    

    可能工作

    没有办法测试它,但取出了刚刚的太空火柴。

        7
  •  0
  •   Lucas Oman    16 年前

    也许吧:

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

    我不是Java程序员,所以我不确定Java ReGEX是否允许“?”