围绕 select 逗号拆分字符串的复杂要求

Complex requirements for string split around select commas

TL;DR

我需要一些帮助来制作一个正则表达式,该正则表达式将匹配一个字符串中的任何逗号,这些逗号并排并且在它们周围和它们之间有无限的白色 space。逗号及其周围的白色 space 不能在匹配的单引号或双引号内。然后我需要从这些逗号周围捕获非白色 space 值并计算其中有多少个逗号。

从逗号周围捕获的值将在最终数组中成为它们自己的值,而被计数的逗号将成为添加到最终数组的 nil 值。

问题说明:

这是一个非常复杂的问题,因此非常感谢您的帮助。我正在为我已经使用了一段时间的库添加功能。我有这个包含数组的字符串

"['d,og,f:asdf,:hello,",,\",,alsee',,,'ho,la', "-123,4,5.3", true,   :good, false,,, "gr\'\'\'true,\',\'ee\"n", ":::testme", true]"

我想仅围绕 select 逗号拆分此字符串,以便我有一个包含以下值的数组

'd,og,f:asdf,:hello,",,\",,alsee'
nil
nil
'ho,la'
"-123,4,5.3"
true
:good
false
nil
nil
"gr\'\'\'true,\',\'ee\"n"
":::testme"
true

然后 nil 值来自不包含在任何字符串中的并排逗号。我写了下面的正则表达式来拆分上面的字符串(我已经去掉了开始和结束括号):

/(?<=(?:['\"]|false|true|^|,)),(?=(?:\s*(?:(?::[\w]+)|(?:(?::?(?:\"[\s\S]*\")|(?:'[\s\S]*'))|(?:false|true)))\s*(?:,|$)))/

这会拆分字符串,所以我得到这些值:

(0) "'d,og,f:asdf,:hello,",,\",,alsee',,"
(1) "'ho,la'"
(2) " "-123,4,5.3""
(3) " true"
(4) "   :good, false,,"
(5) " "gr\'\'\'true,\',\'ee\"n""
(6) " ":::testme""
(7) " true"

所有值都是字符串,可以从它们周围的双引号中看出。不过,他们不会都以这种方式结束。 true 或 false 将转换为布尔值。内部引号包围的值将以字符串形式结束。然后以 : 开头的值将作为符号结束。

索引 04 处的值存在问题。索引 0 应该是这样的:

(0.0) "'d,og,f:asdf,:hello,",,\",,alsee'"
(0.1) nil
(0.2) nil

如你所见,末尾的两个逗号没有了。它们已成为您在上面看到的两个 nil 值。然后字符串从第一个单引号开始到最后一个单引号结束,表示数组中的这个值是一个字符串。

那么索引4" :good, false,,")应该是这样的:

(4.0) "   :good"
(4.1) " false"
(4.2) nil
(4.3) nil

最后的两个逗号变成了nil。然后 " false" 是它自己的值,稍后将转换为布尔值,而 " :good" 也是它自己的值,稍后将转换为符号。

为了解决索引 4 的问题,我通过第二个正则表达式获得了所有值 运行。这是:

/^(\s*:(?:(?:[\w]+|\"[\s\S]+\"|'[\s\S]+')\s*)),([\s\S]*)$/

我没有拆分这个,而是得到了捕获组。它最终返回此数组以获取索引 4:

处的值
(4.0) "   :good"
(4.1) " false,,"

这就是我想要的,除了一个问题。索引 4.1 (" false,,") 处的值有两个尾随逗号,它们应该是数组中的 nil 个值。

我需要一些帮助来制作一个正则表达式,该正则表达式将匹配一个字符串中的任何逗号,这些逗号并排并且在它们周围和它们之间有无限的白色 space。逗号及其周围的白色 space 不能在匹配的单引号或双引号内。然后我需要从这些逗号周围捕获非白色 space 值并计算其中有多少个逗号。

从逗号周围捕获的值将在最终数组中成为它们自己的值,而被计数的逗号将成为添加到最终数组的 nil 值。

['d,og,f:asdf,:hello," ,\ ",alsee','ho,la', " -123,4,5.3 ", true, :good, false, " 格\ '\' 我数了4根弦。 3 个用双引号,最后一个用单引号? 你说这被你的正则表达式分解成更小的字符串。但是4个字符串之外的字符呢? 抱歉,看起来有点乱。 尝试将其全部放在此处的文档字符串中,然后通过正则表达式将其分解。

我终于自己弄明白了。如果您查看上面问题的描述,您可以了解它与其余部分的匹配程度。

/^(([\s]*,)*)[\s]*((?::[\w]+)|(?::?(?:\"[\s\S]*\")|(?:'[\s\S]*')|false|true))?(([\s]*,)*)$/