当前位置:  开发笔记 > 编程语言 > 正文

如何在JavaScript中使用类似于PHP的preg_match_all()的正则表达式匹配多次出现?

如何解决《如何在JavaScript中使用类似于PHP的preg_match_all()的正则表达式匹配多次出现?》经验,为你挑选了6个好方法。

我试图解析是由由两种分离的key = value对的URL编码的字符串&&.

以下内容仅匹配第一次出现,将键和值分解为单独的结果元素:

var result = mystring.match(/(?:&|&)?([^=]+)=([^&]+)/)

字符串'1111342 = Adam%20Franco&348572 = Bob%20Jones'的结果将是:

['1111342', 'Adam%20Franco']

使用全局标志'g'将匹配所有匹配项,但仅返回完全匹配的子字符串,而不是分离的键和值:

var result = mystring.match(/(?:&|&)?([^=]+)=([^&]+)/g)

字符串'1111342 = Adam%20Franco&348572 = Bob%20Jones'的结果将是:

['1111342=Adam%20Franco', '&348572=Bob%20Jones']

虽然我可以&单独拆分字符串并分别拆分每个键/值对,但有没有办法使用JavaScript的正则表达式支持来匹配模式的多次出现,/(?:&|&)?([^=]+)=([^&]+)/类似于PHP的preg_match_all()函数?

我的目标是通过某种方式获得结果,子匹配分开如下:

[['1111342', '348572'], ['Adam%20Franco', 'Bob%20Jones']]

要么

[['1111342', 'Adam%20Franco'], ['348572', 'Bob%20Jones']]

Tomalak.. 155

我建议使用替代正则表达式,使用子组单独捕获参数的名称和值:

function getUrlParams(url) {
  var re = /(?:\?|&(?:amp;)?)([^=&#]+)(?:=?([^&#]*))/g,
      match, params = {},
      decode = function (s) {return decodeURIComponent(s.replace(/\+/g, " "));};

  if (typeof url == "undefined") url = document.location.href;

  while (match = re.exec(url)) {
    params[decode(match[1])] = decode(match[2]);
  }
  return params;
}

var result = getUrlParams("http://maps.google.de/maps?f=q&source=s_q&hl=de&geocode=&q=Frankfurt+am+Main&sll=50.106047,8.679886&sspn=0.370369,0.833588&ie=UTF8&ll=50.116616,8.680573&spn=0.35972,0.833588&z=11&iwloc=addr");

result 是一个对象:

{
  f: "q"
  geocode: ""
  hl: "de"
  ie: "UTF8"
  iwloc: "addr"
  ll: "50.116616,8.680573"
  q: "Frankfurt am Main"
  sll: "50.106047,8.679886"
  source: "s_q"
  spn: "0.35972,0.833588"
  sspn: "0.370369,0.833588"
  z: "11"
}

正则表达式分解如下:

(?:            # non-capturing group
  \?|&         #   "?" or "&"
  (?:amp;)?    #   (allow "&", for wrongly HTML-encoded URLs)
)              # end non-capturing group
(              # group 1
  [^=&#]+      #   any character except "=", "&" or "#"; at least once
)              # end group 1 - this will be the parameter's name
(?:            # non-capturing group
  =?           #   an "=", optional
  (            #   group 2
    [^&#]*     #     any character except "&" or "#"; any number of times
  )            #   end group 2 - this will be the parameter's value
)              # end non-capturing group

这就是我所希望的.我在JavaScript文档中从未见过的是,如果多次调用,exec()方法将继续返回下一个结果集.再次感谢您的精彩提示! (23认同)


meouw.. 66

您需要使用'g'开关进行全局搜索

var result = mystring.match(/(&|&)?([^=]+)=([^&]+)/g)

这实际上并没有解决问题:"使用全局标志'g'将匹配所有匹配项,但只返回完全匹配的子字符串,而不是分离的键和值." (32认同)


Mike 'Pomax'.. 38

如果你不想依赖运行exec风格匹配所带来的"盲目匹配" ,那么JavaScript确实带有内置的全匹配功能,但它是replace函数调用的一部分,当使用"如何处理捕获"时小组" 处理功能:

var data = {};

var getKeyValue = function(fullPattern, group1, group2, group3) {
  data[group2] = group3;
};

mystring.replace(/(?:&|&)?([^=]+)=([^&]+)/g, getKeyValue);

完成.

而不是使用捕获组处理功能实际上返回替换字符串(用于更换处理时,第一个参数,叫做a这里,是完整的模式匹配,以及随后的ARG游戏单个捕获组,在这种情况下b为1组,c2组,等)我们只需捕获第2组和第3组,并缓存该对.

因此,不要编写复杂的解析函数,请记住JavaScript中的"matchAll"函数只是用替换处理函数"替换",并且可以获得很多模式匹配效率.



1> Tomalak..:

我建议使用替代正则表达式,使用子组单独捕获参数的名称和值:

function getUrlParams(url) {
  var re = /(?:\?|&(?:amp;)?)([^=&#]+)(?:=?([^&#]*))/g,
      match, params = {},
      decode = function (s) {return decodeURIComponent(s.replace(/\+/g, " "));};

  if (typeof url == "undefined") url = document.location.href;

  while (match = re.exec(url)) {
    params[decode(match[1])] = decode(match[2]);
  }
  return params;
}

var result = getUrlParams("http://maps.google.de/maps?f=q&source=s_q&hl=de&geocode=&q=Frankfurt+am+Main&sll=50.106047,8.679886&sspn=0.370369,0.833588&ie=UTF8&ll=50.116616,8.680573&spn=0.35972,0.833588&z=11&iwloc=addr");

result 是一个对象:

{
  f: "q"
  geocode: ""
  hl: "de"
  ie: "UTF8"
  iwloc: "addr"
  ll: "50.116616,8.680573"
  q: "Frankfurt am Main"
  sll: "50.106047,8.679886"
  source: "s_q"
  spn: "0.35972,0.833588"
  sspn: "0.370369,0.833588"
  z: "11"
}

正则表达式分解如下:

(?:            # non-capturing group
  \?|&         #   "?" or "&"
  (?:amp;)?    #   (allow "&", for wrongly HTML-encoded URLs)
)              # end non-capturing group
(              # group 1
  [^=&#]+      #   any character except "=", "&" or "#"; at least once
)              # end group 1 - this will be the parameter's name
(?:            # non-capturing group
  =?           #   an "=", optional
  (            #   group 2
    [^&#]*     #     any character except "&" or "#"; any number of times
  )            #   end group 2 - this will be the parameter's value
)              # end non-capturing group


这就是我所希望的.我在JavaScript文档中从未见过的是,如果多次调用,exec()方法将继续返回下一个结果集.再次感谢您的精彩提示!

2> meouw..:

您需要使用'g'开关进行全局搜索

var result = mystring.match(/(&|&)?([^=]+)=([^&]+)/g)


这实际上并没有解决问题:"使用全局标志'g'将匹配所有匹配项,但只返回完全匹配的子字符串,而不是分离的键和值."

3> Mike 'Pomax'..:

如果你不想依赖运行exec风格匹配所带来的"盲目匹配" ,那么JavaScript确实带有内置的全匹配功能,但它是replace函数调用的一部分,当使用"如何处理捕获"时小组" 处理功能:

var data = {};

var getKeyValue = function(fullPattern, group1, group2, group3) {
  data[group2] = group3;
};

mystring.replace(/(?:&|&)?([^=]+)=([^&]+)/g, getKeyValue);

完成.

而不是使用捕获组处理功能实际上返回替换字符串(用于更换处理时,第一个参数,叫做a这里,是完整的模式匹配,以及随后的ARG游戏单个捕获组,在这种情况下b为1组,c2组,等)我们只需捕获第2组和第3组,并缓存该对.

因此,不要编写复杂的解析函数,请记住JavaScript中的"matchAll"函数只是用替换处理函数"替换",并且可以获得很多模式匹配效率.


听起来你应该在Stackoverflow上发布一个问题,而不是试图在评论中解决它.

4> Aram Kochary..:

对于捕获组,我习惯preg_match_all在PHP中使用,我试图在这里复制它的功能:



@teh_senaus你需要用`/ g'指定全局修饰符,否则运行`exec()`将不会改变当前索引并将永远循环.

5> Gumbo..:

设置g全局匹配的修饰符:

/…/g


这实际上并没有解决问题:"使用全局标志'g'将匹配所有匹配项,但只返回完全匹配的子字符串,而不是分离的键和值."

6> KIM Taegyoon..:

资料来源:https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec

寻找连续的比赛

如果正则表达式使用"g"标志,则可以多次使用exec()方法在同一字符串中查找连续匹配.执行此操作时,搜索从正则表达式的lastIndex属性指定的str的子字符串开始(test()也将提前执行​​lastIndex属性).例如,假设您有此脚本:

var myRe = /ab*/g;
var str = 'abbcdefabh';
var myArray;
while ((myArray = myRe.exec(str)) !== null) {
  var msg = 'Found ' + myArray[0] + '. ';
  msg += 'Next match starts at ' + myRe.lastIndex;
  console.log(msg);
}

此脚本显示以下文本:

Found abb. Next match starts at 3
Found ab. Next match starts at 912

注意:不要将正则表达式文字(或RegExp构造函数)放在while条件中,否则如果匹配则会产生无限循环,因为每次迭代都会重置lastIndex属性.还要确保设置了全局标志,或者此处也会出现循环.

推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有