正则表达式以匹配管道分隔字符串数组的模式

Regex to match pattern for pipe separated string array

我正在使用 Ruby 并且我有一个格式如下的字符串:

id,part#,foreign_key_id,false

id,part#,foreign_key_id,false|id,part#,foreign_key_id,true

实际数据看起来像这样:

253,RFTL 9984.0,588,false

可能有一个数组有 0 个竖线分隔符,也可能有多个数组有多个分隔符。 我正在使用以下正则表达式来匹配数组数据:

/\d*,.*,\d*,(true|false)/

但是,我不确定如何用 0 个或多个数组来解释 0 个或多个 | 个字符。我考虑过使用我的原始字符串并将其拆分为 | 然后检查数组的每个索引是否与我上面的正则表达式匹配,但这比匹配整个字符串要慢得多,因为我必须遍历每个数组索引,所以我正在寻找一个正则表达式模式来匹配整个字符串。

您可以使用这个正则表达式 - https://regex101.com/r/wLyNPv/1/

模式:^(?:\d*,[^,]*,\d*,(?:true|false)\|?)+(?<!\|)$

你的模式发生了变化

  • [^,]* 而不是 .*。确保逗号后没有匹配的字符
  • \|? - 可选地匹配文字 |
  • ^(?:\d*,[^,]*,\d*,(?:true|false)\|?)+ - 匹配数组1次或多次
  • (?<!\|)$ - 使用负后视来确保 | 不在字符串的末尾

您可以使用展开循环的方法,首先匹配模式,然后选择性地重复 | 后跟相同的模式。

  • 如果不需要捕获组的值,可以设为非捕获(?:true|false)
  • 这部分.*先匹配到字符串末尾,会造成一些回溯。如果不想匹配逗号,可以使用否定字符 class [^.]+
  • 使用\d* 将匹配可选数字。如果至少应该有一个数字,您可以使用 \d+

模式可能看起来像

\A(\d+,[^,]+,\d+,(?:true|false))(?:\|\d+,[^,]+,\d+,(?:true|false))*\z

Rubular demo

或者使用第一个模式的捕获组,并递归第一个子模式。

\A(\d+,[^,]+,\d+,(?:true|false))(?:\|\g<1>)*\z

Rubular demo