PHP의 preg_match_all()과 유사한 자바스크립트의 regex와 다중 발생을 일치시키는 방법은 무엇입니까?
key된 url-값된 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']
가 그 &
값 쌍을 키합니다의 시킬 수 있는 요. 자바스크립트의 정규 표현식 지원을 사용하여 패턴의 여러 발생을 일치시키는 방법이 없을까요?/(?:&|&)?([^=]+)=([^&]+)/
PHP와 preg_match_all()
기능?
하위 매치를 다음과 같이 분리하여 결과를 얻을 수 있는 방법을 찾고 있습니다.
[['1111342', '348572'], ['Adam%20Franco', 'Bob%20Jones']]
아니면
[['1111342', 'Adam%20Franco'], ['348572', 'Bob%20Jones']]
댓글에서 올리기
2020년 코멘트: regex를 사용하는 것보다, 우리는 이제 이 모든 것을 우리에게 해주는, 그래서 regex는 말할 것도 없고, 커스텀 코드는 더 이상 필요하지 않습니다.
브라우저 지원은 여기 https://caniuse.com/ # feat= url 검색 파라미터에 나와 있습니다.
하위 그룹을 사용하여 매개 변수의 이름과 값을 개별적으로 캡처하고 다음과 같은 대안 정규식을 제안합니다.
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"지오코드: ""hl: "de"즉, "UTF8"iwloc: "addr"ll: "50.116616,8. 680573"q: 프랑크푸르트암마인sll: "50.106047,8.679886"출처: "s_q"spn: "0.35972,0.833588"sspn: "0.370369,0.833588"z: "11"}
정규군은 다음과 같이 분류됩니다.
(?: # capturing이 아닌 그룹\?|& # "?" 또는 "&"(?:amp;?# (잘못된 HTML 인코딩 URL의 경우 "&" 허용)) # 끝 비capturing 그룹( # 1조[^=&#]+ # "=", "&" 또는 "#"을 제외한 모든 문자를 한 번 이상) # end group 1 - 파라미터의 이름이 됩니다.(?: # capturing이 아닌 그룹=? # "=",선택적.( # 2조[^&#]* # "&" 또는 "#"을 제외한 모든 문자, 횟수) # end group 2 - 이 값이 파라미터의 값이 됩니다.) # 끝 비capturing 그룹
글로벌 검색을 위해서는 'g' 스위치를 사용해야 합니다.
var result = mystring.match(/(&|&)?([^=]+)=([^&]+)/g)
2020년 편집
이 작업은 더 이상 어떤 종류의 사용자 지정 코드를 필요로 하지 않으므로 URL 검색 매개변수를 사용합니다.브라우저는 단일 컨스트럭터로 이 작업을 수행할 수 있습니다.
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" ]
따라서 더 이상 이것에 regex를 사용할 이유가 없습니다.
원답
실행 스타일 매칭과 함께 제공되는 "블라인드 매칭"에 의존하고 싶지 않다면, 자바스크립트는 match-all 기능이 내장되어 있지만, "캡처 그룹으로 무엇을 할 것인가" 처리 기능을 사용할 때는 함수 호출의 일부입니다.
var data = {};
var getKeyValue = function(fullPattern, group1, group2, group3) {
data[group2] = group3;
};
mystring.replace(/(?:&|&)?([^=]+)=([^&]+)/g, getKeyValue);
다 했어요.
캡처 그룹 핸들링 함수를 사용하여 실제로 대체 문자열을 반환하는 대신(대체 핸들링의 경우 첫 번째 arg는 전체 패턴 일치이고, 후속 arg는 개별 캡처 그룹) 그룹 2와 3 캡처를 사용하여 해당 쌍을 캐시합니다.
따라서 복잡한 구문 분석 기능을 작성하기보다는 자바스크립트의 "matchAll" 기능이 단순히 대체 핸들러 기능으로 "교체"되어 패턴 매칭 효율성이 높다는 것을 기억해야 합니다.
를 .preg_match_all
PHP에서 그 기능을 복제하려고 했습니다.
<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>
g
전역 일치에 대한 수식어:
/…/g
:
://
연속 일치 항목 찾기
정규식에서 "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 조건 내에 배치하지 마십시오. 그렇지 않으면 각 반복 시 마지막 Index 속성이 재설정되어 일치하는 경우 무한 루프가 생성됩니다.또한 글로벌 플래그가 설정되어 있거나 여기서도 루프가 발생하는지 확인합니다.
2020년 е로.String.prototype.matchAll()을 알려드리겠습니다.
let regexp = /(?:&|&)?([^=]+)=([^&]+)/g;
let str = '1111342=Adam%20Franco&348572=Bob%20Jones';
for (let match of str.matchAll(regexp)) {
let [full, key, value] = match;
console.log(key + ' => ' + value);
}
출력:
1111342 => Adam%20Franco
348572 => Bob%20Jones
만약 (나와 같은) 누군가가 배열을 지원하는 토말락의 방법(즉, 다중 선택)을 필요로 한다면, 다음과 같습니다.
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
(반품된 earlier만 해당:
제목에서 알 수 있듯이 제안된 질문을 고수하기 위해 실제로 각 경기를 문자열로 반복할 수 있습니다.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?");
위를 실행한 후,words
다음과 같습니다.
[
{
"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
}
]
PHP에서 사용할 수 있는 것과 유사한 여러 가지 경우를 일치시키기 위해 당신은 이 유형의 사고를 사용하여 당신만의 것을 만들거나 다음과 같은 것을 사용할 수 있습니다. 당신의 JS는 이 함수를 다음과 같이 정의합니다.
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;
}
당신이 사용하는 것을 피할 수 있다면,map
이것은 4줄 solution입니다.
var mystring = '1111342=Adam%20Franco&348572=Bob%20Jones';
var result = mystring.match(/(&|&)?([^=]+)=([^&]+)/g) || [];
result = result.map(function(i) {
return i.match(/(&|&)?([^=]+)=([^&]+)/);
});
console.log(result);
예쁘지도 않고 효율적이지도 않지만 적어도 컴팩트합니다. ;)
사용하다window.URL
:
> 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"]]
같은 이름을 사용하여 여러 개의 파라미터를 캡처하기 위해 토말락의 방법으로 while loop을 다음과 같이 수정했습니다.
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"]}
음... 저도 비슷한 문제가 있었어요...RegExp를 사용한 증분/단계 검색을 원합니다(예: 검색 시작...).처리를 좀...마지막 일치까지 검색 계속)
많은 인터넷 검색 끝에...늘 그래왔던 것처럼 (이제는 습관이 되어가고 있어요) 결국 스택오버플로우에 들어갔고 답을 찾았죠...
언급되지 않은 것과 언급해야 할 사항은 "lastIndex
" RegExp 개체가 "을(를) 구현하는 이유를 이제 이해했습니다.lastIndex
" 소유물
내가 보기엔 그것을 나누는 것이 최선의 선택인 것 같습니다.
'1111342=Adam%20Franco&348572=Bob%20Jones'.split('&').map(x => x.match(/(?:&|&)?([^=]+)=([^&]+)/))
정규 지옥을 피하기 위해 첫 번째 매치를 찾을 수 있습니다. 청크를 잘라낸 다음 서브스트링에서 다음 매치를 찾으십시오.C#에서는 이와 같습니다. 자바스크립트로 포팅하지 않아서 죄송합니다.
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;
언급URL : https://stackoverflow.com/questions/520611/how-can-i-match-multiple-occurrences-with-a-regex-in-javascript-similar-to-phps
'programing' 카테고리의 다른 글
jquery.animate()가 있는 CSS 회전 교차 브라우저 (0) | 2023.09.26 |
---|---|
JQuery에 추천하는 자바스크립트 HTML 템플릿 라이브러리? (0) | 2023.09.26 |
Spring Boot에서 '@DateTimeFormat' 패턴을 글로벌하게 구성하는 방법은? (0) | 2023.09.26 |
워드 프레스 페이지에서 "http"를 "https"로 모두 변경 (0) | 2023.09.26 |
.prop('checked', false) 또는 .removeAtr('checked')? (0) | 2023.09.26 |