微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

正则表达式以逗号分隔参数列表,但忽略引号中的逗号

如何解决正则表达式以逗号分隔参数列表,但忽略引号中的逗号

我需要解析一个字符串,它是一个逗号分隔的表单参数列表

key1=value1,key2=value2,key3=value3...

复杂的是值可以用引号括起来,以允许它们包含空格和逗号等。当然,引号括起来的逗号不应该算作分隔参数。 (在引号之外的不同地方也可以有空格,可能应该被忽略。)

我的想法是在逗号处拆分列表,然后在每个参数定义中,将键与等号处的值分开。所以要split参数,我需要找到有效的(不是引号);我认为正则表达式是简洁和直接的方式。

以下是一些示例字符串:

  • Include="All Violations",CheckType=MaxTrans
  • MetricName = PlacedInstances,PlacedOnly = 1
  • CheckType=Hold,Include="reg2reg,in2reg,in2out,reg2out"
  • CheckType=Setup,reg2out(原文如此)

是的,最后一个格式很差:值中缺少一个终止引号。

我发现 this answer 很有帮助(正则表达式:/,(?=(?:(?:[^"]*"){2})*[^"]*$)/),除了解析格式不佳的那个。在我的例子中,我在等号中有额外的信息,这将允许解析那个。

我试过这个:(/(?<==[^"]+),/,它适用于格式不佳的,但我的第一个例子失败了。我认为我需要的是一种方法来查找前面有等号但在它们和前面的第一个等号之间有零个或两个引号(不仅仅是单引号)的逗号。但是我如何在 Javascript Regex 中编写它?

解决方法

人们可以使用一种基于例如的方法两个正则表达式...

  1. /,\s*(?=[^=,]+=)/
  2. /^(?<key>[^=\s]+)\s*="*(?<value>[^"]+)/

第一个必须根据 OP 的要求 split 提供的字符串;因此它基于 positive lookahead

第二个将在执行 map 参数模板 项的结果数组的操作中使用。每个项目都将由尝试 capture named groups 的正则表达式处理。此外,groupvalue 字段的字符串值将被 trimmed.

// see ... [https://regex101.com/r/nUc8en/1/]
const regXParameterSplit = (/,]+=)/);

// see ... [https://regex101.com/r/7xSwyX/1/]
const regXCaptureKeyValue = (/^(?<key>[^=\s]+)\s*="*(?<value>[^"]+)/);

const testSample = 'Include="All Violations",CheckType=MaxTrans,MetricName = PlacedInstances,PlacedOnly = 1,CheckType=Hold,Include="reg2reg,in2reg,in2out,reg2out",CheckType=Setup,reg2out,CheckType=Setup';

function getKeyAndValue(template) {
  const { groups } = (regXCaptureKeyValue.exec(template) || {});
  if (groups) {
    groups.value = groups.value.trim();
  }
  return groups;
}

console.log(
  '... just splitting ...',testSample
    .split(regXParameterSplit)
);
console.log(
  '... the full approach ...',testSample
    .split(regXParameterSplit)
    .map(getKeyAndValue)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

,

这样的事情会起作用:

/(?:^|,*)(?<key>[a-z]+) *= *(?<value>[^\r\n,"]+|"[^\r\n"]+"?)/gmi

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

  • (?:^|,*)(?<key>[a-z]+) 命名一个捕获组“键”,它被定义为位于行首或逗号和可选空格之后的一系列 alpha 字符
  • *= * - 赋值运算符(等号)的两边可以有空格
  • (?<value>[^\r\n,"]+|"[^\r\n"]+"?) - 将捕获组命名为“值”,它可以是一个非逗号和非引号包含的字符串,或者如果它以引号开头,则它可以包含带有可选结束引号的逗号

但是如果你有像 Include="All Viola\"tions" 这样的数据,那么它就会失败。

请注意,我避免使用后视,因为并非所有浏览器都普遍支持它们。

,

使用

string.match(/\w+\s*=\s*(?:"[^"\n]*(?:"|$)|\S+(?=,|$))/g)

proof

说明

--------------------------------------------------------------------------------
  \w+                      word characters (a-z,A-Z,0-9,_) (1 or
                           more times (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  \s*                      whitespace (\n,\r,\t,\f,and " ") (0 or
                           more times (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  =                        '='
--------------------------------------------------------------------------------
  \s*                      whitespace (\n,and " ") (0 or
                           more times (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  (?:                      group,but do not capture:
--------------------------------------------------------------------------------
    "                        '"'
--------------------------------------------------------------------------------
    [^"\n]*                  any character except: '"','\n'
                             (newline) (0 or more times (matching the
                             most amount possible))
--------------------------------------------------------------------------------
    (?:                      group,but do not capture:
--------------------------------------------------------------------------------
      "                        '"'
--------------------------------------------------------------------------------
     |                        OR
--------------------------------------------------------------------------------
      $                        before an optional \n,and the end of
                               the string
--------------------------------------------------------------------------------
    )                        end of grouping
--------------------------------------------------------------------------------
   |                        OR
--------------------------------------------------------------------------------
    \S+                      non-whitespace (all but \n,and " ") (1 or more times (matching the
                             most amount possible))
--------------------------------------------------------------------------------
    (?=                      look ahead to see if there is:
--------------------------------------------------------------------------------,','
--------------------------------------------------------------------------------
     |                        OR
--------------------------------------------------------------------------------
      $                        before an optional \n,and the end of
                               the string
--------------------------------------------------------------------------------
    )                        end of look-ahead
--------------------------------------------------------------------------------
  )                        end of grouping

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。