【问题标题】:Regex to split text ignoring occurrences of delimiter(s) in quoted text正则表达式拆分文本,忽略引用文本中出现的分隔符
【发布时间】:2018-04-20 15:46:07
【问题描述】:

在给定一组分隔符(例如;,)的情况下,我将如何编写正则表达式,我可以在这些示例中得到以下结果:

coffee, water; tea -> [coffee, water, tea]
"coffee, black;", water; tea -> ["coffee, black;", water, tea]

为了澄清,常规文本不能有空格,引用文本可以有空格,引号内的分隔符被忽略,所有文本都由分隔符分隔。

我自己一直在尝试使用正则表达式,但没有得到我想要的结果。我也在没有前瞻/后视的环境中工作。关于如何实现这一点的任何想法?

【问题讨论】:

  • 什么实现了 split ?通常拆分为\s*(?:("[^"]*")|[,;])\s*
  • 只是为了确定:black 不应该在第二个结果列表中吗?
  • @raul.vila 把球丢在那里。谢谢。
  • @m0meni 如果值不包含在引号中,是否可以包含空格字符?
  • \s*(?:("[^"]*")\s*[,;]|[,;])\s* 更准确。在 Perl 中,这将在元素位于捕获组内时创建一个元素。否则,它会去除分隔符(此处为空格和 [,;] )

标签: regex parsing delimiter re2


【解决方案1】:

这里有个好办法(?:\r?\n|[,;]|^)[^\S\r\n]*((?:(?:[^\S\r\n]*[^,;"\s])*(?:"[^"]*")?[^,;"\s]*))[^\S\r\n]*

为其添加了一些 WSp 装饰。
很好的演示在这里 -> https://regex101.com/r/FsJtOE/1

捕获组 1 包含该元素。
一个简单的发现一切都应该工作。

注意,使用 Re2 没有断言,而是处理所有角落
它真的需要它们。

不幸的是,这与您使用该正则表达式引擎所能达到的一样接近。

这样做的一件事是允许在非引号字段中有多个单词。

可读版本

 # Validate even quotes:  ^[^"]*(?:"[^"]*"[^"]*)*$   
 # Then -> 
 # ----------------------------------------------
 # Find all:  

 (?: \r? \n | [,;] | ^ )
 [^\S\r\n]* 
 (                             # (1 start)
      (?:
           (?:
                [^\S\r\n]* 
                [^,;"\s] 
           )*
           (?: " [^"]* " )?
           [^,;"\s]*  
      )
 )                             # (1 end)
 [^\S\r\n]* 

【讨论】:

  • 我给出了符合要求的最简单的解决方案。如果要求比问题中的要求更复杂,您的回答会增加一个很好的选择。但我会选择最简单的可行的,以使维护更容易。
  • @raul.vila - 你的回答很好。现实世界更复杂。不过,尤其是 Re2..
【解决方案2】:

替换:

((\"[^\"]*\")|[a-zA-Z]+)[,;]

与:

$1,

会给你括号内的内容。

解释:

  • ((\"[^\"]*\")|[a-zA-Z]+) 这两个选项中的任何一个:
    • (\"[^\"]*\") 双引号之间的任何内容
    • [a-zA-Z]+ 任意字符序列
  • [,;] ,; 的任何出现

See on regex101,使用此输入:

coffee, water; tea
"coffee, black;", water; tea

你得到这个输出:

coffee, water, tea
"coffee, black;", water, tea

【讨论】:

  • 欢迎投票解释。我想知道哪里出了问题。
【解决方案3】:

不确定您使用的是什么风格的正则表达式,排除了前瞻的使用,但这样的东西对您有用吗?

/".*"|[^;,"\s]+/

在尝试排除分隔符、引号和空格的值(使用负字符类 [^;,"\s]+)之前,它首先检查带引号的值(使用 ".*"

https://regex101.com/r/zWea28/1/

【讨论】:

  • 您的解决方案只需稍作调整即可用于替换:regex101.com/r/zWea28/2 不确定是否可以更清洁。
  • @raul.vila 不错的变种。
猜你喜欢
  • 1970-01-01
  • 2022-01-17
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-07
  • 1970-01-01
相关资源
最近更新 更多