Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/449.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用类似于PHP';的JavaScript中的正则表达式匹配多个事件;s preg_match_all()?_Javascript_Regex - Fatal编程技术网

如何使用类似于PHP';的JavaScript中的正则表达式匹配多个事件;s preg_match_all()?

如何使用类似于PHP';的JavaScript中的正则表达式匹配多个事件;s preg_match_all()?,javascript,regex,Javascript,Regex,我试图解析url编码的字符串,这些字符串由键=值对组成,由&或&;分隔 以下内容仅与第一个匹配,将键和值拆分为单独的结果元素: var result = mystring.match(/(?:&|&)?([^=]+)=([^&]+)/) 字符串“1111342=Adam%20Franco&348572=Bob%20Jones”的结果为: ['1111342', 'Adam%20Franco'] ['1111342=Adam%20Franco', '&am

我试图解析url编码的字符串,这些字符串由键=值对组成,由
&
&;分隔

以下内容仅与第一个匹配,将键和值拆分为单独的结果元素:

var result = mystring.match(/(?:&|&)?([^=]+)=([^&]+)/)
字符串“1111342=Adam%20Franco&348572=Bob%20Jones”的结果为:

['1111342', 'Adam%20Franco']
['1111342=Adam%20Franco', '&348572=Bob%20Jones']
使用全局标志“g”将匹配所有匹配项,但仅返回完全匹配的子字符串,而不是单独的键和值:

var result = mystring.match(/(?:&|&)?([^=]+)=([^&]+)/g)
字符串“1111342=Adam%20Franco&348572=Bob%20Jones”的结果为:

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

我的目标是通过将子匹配分开来获得结果,如:

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


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

/…/g

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

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

已从评论中删除

2020年评论:我们不再使用正则表达式,而是使用正则表达式,它为我们完成了所有这些,因此不再需要自定义代码,更不用说正则表达式了

此处列出了浏览器支持


我建议使用另一种正则表达式,使用子组分别捕获参数的名称和值,并:

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" } { f:“q” 地理编码:“ hl:“德” ie:“UTF8” iwloc:“地址” LH:“50.116616,8.680573” 问:“法兰克福美茵河畔” sll:“50.106047,8.679886” 资料来源:“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
[
  {
    "match": "Where",
    "remainder": " in the world is Carmen Sandiego?",
    "index": 0
  },
  {
    "match": "in",
    "remainder": " the world is Carmen Sandiego?",
    "index": 6
  },
  {
    "match": "the",
    "remainder": " world is Carmen Sandiego?",
    "index": 9
  },
  {
    "match": "world",
    "remainder": " is Carmen Sandiego?",
    "index": 13
  },
  {
    "match": "is",
    "remainder": " Carmen Sandiego?",
    "index": 19
  },
  {
    "match": "Carmen",
    "remainder": " Sandiego?",
    "index": 22
  },
  {
    "match": "Sandiego",
    "remainder": "?",
    "index": 29
  }
]
function matchAll(str, rgx) {
  var arr, extras, matches = [];
  str.replace(rgx.global ? rgx : new RegExp(rgx.source, (rgx + '').replace(/[\s\S]+\//g , 'g')), function() {
    matches.push(arr = [].slice.call(arguments));
    extras = arr.splice(-2);
    arr.index = extras[0];
    arr.input = extras[1];
  });
  return matches[0] ? matches : null;
}
(?:#非捕获组 \|&#“?”或“&” (?:amp;)?#(允许“&;”,用于错误的HTML编码URL) )#结束非捕获组 (#第一组) [^=&#]+#除“=”、“&”或“#”之外的任何字符至少一次 )#结束组1-这将是参数的名称 (?:#非捕获组 =?#一个“=”,可选 (#第2组) [^&#]*#除“&”或“#”以外的任何字符,任意次数 )#结束组2-这将是参数的值 )#结束非捕获组
为了捕获组,我习惯于在PHP中使用
preg\u match\u all
,我尝试在这里复制它的功能:

<script>

// Return all pattern matches with captured groups
RegExp.prototype.execAll = function(string) {
    var match = null;
    var matches = new Array();
    while (match = this.exec(string)) {
        var matchArray = [];
        for (i in match) {
            if (parseInt(i) == i) {
                matchArray.push(match[i]);
            }
        }
        matches.push(matchArray);
    }
    return matches;
}

// Example
var someTxt = 'abc123 def456 ghi890';
var results = /[a-z]+(\d+)/g.execAll(someTxt);

// Output
[["abc123", "123"],
 ["def456", "456"],
 ["ghi890", "890"]]

</script>

//返回捕获组的所有模式匹配
RegExp.prototype.execAll=函数(字符串){
var match=null;
var matches=新数组();
while(match=this.exec(字符串)){
var matchArray=[];
因为(我在比赛中){
if(parseInt(i)=i){
matchArray.push(匹配[i]);
}
}
matches.push(匹配数组);
}
返回比赛;
}
//范例
var someTxt='abc123 def456 ghi890';
var results=/[a-z]+(\d+)/g.execAll(someTxt);
//输出
[“abc123”,“123”],
[“def456”,“456”],
[“ghi890”,“890”]]

嗯。。。我也有类似的问题。。。 我需要使用RegExp进行增量/分步搜索 (例如:开始搜索…进行一些处理…继续搜索直到最后一次匹配)

经过大量的网络搜索。。。像往常一样(现在这已成为一种习惯) 我最终在StackOverflow找到了答案

没有提及的内容和需要提及的事项是“
lastIndex

现在我明白了为什么RegExp对象实现了“
lastIndex
”属性

”以使用相同的名称捕获多个参数,我修改了Tomalak方法中的while循环,如下所示:

  while (match = re.exec(url)) {
    var pName = decode(match[1]);
    var pValue = decode(match[2]);
    params[pName] ? params[pName].push(pValue) : params[pName] = [pValue];
  }
输入:
?firstname=george&lastname=bush&firstname=bill&lastname=clinton

返回:
{firstname:[“george”,“bill”],lastname:[“bush”,“clinton”]}

如果有人(像我一样)需要使用支持数组的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)) {
    if( params[decode(match[1])] ) {
        if( typeof params[decode(match[1])] != 'object' ) {
            params[decode(match[1])] = new Array( params[decode(match[1])], decode(match[2]) );
        } else {
            params[decode(match[1])].push(decode(match[2]));
        }
    }
    else
        params[decode(match[1])] = decode(match[2]);
  }
  return params;
}
var urlParams = getUrlParams(location.search);
输入
?my=1&my=2&my=things


结果
1,2,things
(早期仅返回:things)

2020编辑

使用,因为此作业不再需要任何类型的自定义代码。浏览器可以通过单个构造函数为您实现这一点:

const str = "1111342=Adam%20Franco&348572=Bob%20Jones";
const data = new URLSearchParams(str);
for (pair of data) console.log(pair)
屈服

Array [ "1111342", "Adam Franco" ]
Array [ "348572", "Bob Jones" ]
因此,没有理由再使用正则表达式进行此操作

原始答案

如果您不想依赖于运行样式匹配附带的“盲匹配”,JavaScript确实内置了匹配所有功能,但在使用“如何处理捕获组”时,它是函数调用的一部分:

完成了

我们不使用capture group handling函数实际返回替换字符串(对于替换处理,第一个参数是完整模式匹配,后续参数是单独的捕获组),而是简单地获取组2和3捕获,并缓存该对


因此,不要编写复杂的解析函数,记住JavaScript中的“matchAll”函数只是用替换处理程序函数“replace”,可以获得更高的模式匹配效率。

只需坚持标题中提出的问题,实际上,您可以使用
string.prototype.replace()
在字符串中迭代每个匹配项。例如,以下操作仅用于获取基于正则表达式的所有单词的数组:

function getWords(str) {
  var arr = [];
  str.replace(/\w+/g, function(m) {
    arr.push(m);
  });
  return arr;
}

var words = getWords("Where in the world is Carmen Sandiego?");
// > ["Where", "in", "the", "world", "is", "Carmen", "Sandiego"]
如果我想获得捕获组,甚至是每场比赛的索引,我也可以这样做。下面显示了如何返回每个匹配以及整个匹配、第一个捕获组和索引:

function getWords(str) {
  var arr = [];
  str.replace(/\w+(?=(.*))/g, function(m, remaining, index) {
    arr.push({ match: m, remainder: remaining, index: index });
  });
  return arr;
}

var words = getWords("Where in the world is Carmen Sandiego?");
运行上述操作后,
单词将如下所示:

(?: # non-capturing group \?|& # "?" or "&" (?:amp;)? # (allow "&amp;", 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
[
  {
    "match": "Where",
    "remainder": " in the world is Carmen Sandiego?",
    "index": 0
  },
  {
    "match": "in",
    "remainder": " the world is Carmen Sandiego?",
    "index": 6
  },
  {
    "match": "the",
    "remainder": " world is Carmen Sandiego?",
    "index": 9
  },
  {
    "match": "world",
    "remainder": " is Carmen Sandiego?",
    "index": 13
  },
  {
    "match": "is",
    "remainder": " Carmen Sandiego?",
    "index": 19
  },
  {
    "match": "Carmen",
    "remainder": " Sandiego?",
    "index": 22
  },
  {
    "match": "Sandiego",
    "remainder": "?",
    "index": 29
  }
]
function matchAll(str, rgx) {
  var arr, extras, matches = [];
  str.replace(rgx.global ? rgx : new RegExp(rgx.source, (rgx + '').replace(/[\s\S]+\//g , 'g')), function() {
    matches.push(arr = [].slice.call(arguments));
    extras = arr.splice(-2);
    arr.index = extras[0];
    arr.input = extras[1];
  });
  return matches[0] ? matches : null;
}
为了匹配与PHP中可用的类似的多个事件,您可以使用这种类型的思维来创建自己的或使用类似的东西。YourJS或多或少定义了
> s = 'http://www.example.com/index.html?1111342=Adam%20Franco&348572=Bob%20Jones'
> u = new URL(s)
> Array.from(u.searchParams.entries())
[["1111342", "Adam Franco"], ["348572", "Bob Jones"]]
'1111342=Adam%20Franco&348572=Bob%20Jones'.split('&').map(x => x.match(/(?:&|&amp;)?([^=]+)=([^&]+)/))
        long count = 0;
        var remainder = data;
        Match match = null;
        do
        {
            match = _rgx.Match(remainder);
            if (match.Success)
            {
                count++;
                remainder = remainder.Substring(match.Index + 1, remainder.Length - (match.Index+1));
            }
        } while (match.Success);
        return count;
1111342 => Adam%20Franco
348572 => Bob%20Jones