【问题标题】:Intelligent regex to understand input智能正则表达式来理解输入
【发布时间】:2016-09-13 18:55:24
【问题描述】:

跟随Split string that used to be a list,我正在这样做:

console.log(lines[line]);
var regex = /(-?\d{1,})/g;
var cluster = lines[line].match(regex);
console.log(cluster);

这会给我这个:

((3158), (737))
["3158", "737"]

其中 3158 将在我的程序中被视为 ID,而 737 将被视为关联数据。

我想知道是否也有办法处理这种输入:

((3158, 1024), (737))

ID 将是一对,并执行以下操作:

var single_regex = regex_for_single_ID;
var pair_regex = regex_for_pair_ID;
if(single_regex)
  // do my logic
else if(pair_regex)
  // do my other logic
else
  // bad input

这可能吗?


澄清:

我感兴趣的是区别对待这两种情况。例如,一种解决方案是具有这种行为:

((3158), (737))
["3158", "737"]

对于对,连接 ID

((3158, 1024), (737))
["31581024", "737"]

【问题讨论】:

  • 让我澄清一下,您希望得到((3158, 1024), (737)) 的输入并且您想将3158, 1024 匹配为单个ID,对吗?还是您希望将3158 作为ID 和1024 作为ID 匹配并返回两个ID?
  • 单个或成对(-?\d+)(?:\s*,\s*(-?\d+))?-?\d+(?\s*,\s*-?\d+)?(-?\d+(?\s*,\s*-?\d+)?)这取决于你想在数组中看到什么逗号等等...
  • vlaz 已更新。 @sln 嗯,对吗?我的意思是正则表达式是您在代码中拥有的一切吗?如果我这样做,两者都会导致语法错误var regex = ...";
  • 非常正确。在 JS 中你可以像馅饼一样切片,拿走你想要的。有很多方法可以做到这一点。
  • (with delimiters):单个或成对/(-?\d+)(?:\s*,\s*(-?\d+))?//-?\d+(?\s*,\s*-?\d+)?//(-?\d+(?\s*,\s*-?\d+)?)/这取决于你想在数组中看到什么逗号等等。 .

标签: javascript html regex string io


【解决方案1】:

作为一种简单的方法,您可以使用.replace(/(\d+)\s*,\s*/g, '$1') 来成对合并/连接数字,然后使用您已经在使用的简单正则表达式匹配。

示例:

var v1 = "((3158), (737))"; // singular string

var v2 = "((3158, 1024), (737))"; // paired number string

var arr1 = v1.replace(/(\d+)\s*,\s*/g, '$1').match(/-?\d+/g)
//=> ["3158", "737"]

var arr2 = v2.replace(/(\d+)\s*,\s*/g, '$1').match(/-?\d+/g)
//=> ["31581024", "737"]

我们在.replace 中使用这个正则表达式:

/(\d+)\s*,\s*/
  • 它匹配并分组 1 个或多个数字,后跟可选的空格和逗号。
  • 我们使用$1 作为替换,它是我们匹配的数字的反向引用,因此删除了数字后面的空格和逗号。

【讨论】:

  • 太好了,那行得通..你能发布一个正则表达式的解释吗?我正在努力理解他们并学习...... :)
  • 添加了.repalce函数的简要说明。对于match,我正在重用你已经拥有的同一个正则表达式。
【解决方案2】:

您可以使用交替运算符来匹配一对数字(将它们捕获到单独的捕获组中)或单个数字:

/\((-?\d+), (-?\d+)\)|\((-?\d+)\)/g

regex demo

详情

  • \((-?\d+), (-?\d+)\) - 一个(,一个数字(捕获到第1组),一个,,空格,另一个数字对(捕获到第2组)和一个)
  • | - 或
  • \((-?\d+)\) - 一个(,然后是一个数字(捕获到第 3 组)和一个 )

var re = /\((-?\d+), (-?\d+)\)|\((-?\d+)\)/g; 
var str = '((3158), (737)) ((3158, 1024), (737))';
var res = [];
while ((m = re.exec(str)) !== null) {
  if (m[3]) {
    res.push(m[3]);
  } else {
    res.push(m[1]+m[2]);
  }
}
console.log(res);

【讨论】:

  • Wiktor 太棒了,这可以解决问题,但是没有办法让res 也保存其他数据吗?那是 737。因此,例如,它将给出 ["3158", "737"]["31581024", "737"],而不是 ["3158"]["31581024"]
  • 是的,无论你往那里推什么。随意根据您的需要调整代码。关键是如果第 3 组匹配 (if (m[3])),我们知道我们只有一个号码,否则,我们有第 1 组和第 2 组,您可以合并或做任何您想做的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-17
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多