development

Javascript에서 정규식 일치 수 계산

big-blog 2020. 9. 18. 18:47
반응형

Javascript에서 정규식 일치 수 계산


텍스트 청크에서 공백 / 탭 / 개행 수를 계산하는 정규식을 작성하고 싶었습니다. 그래서 순진하게 다음과 같이 썼습니다.

numSpaces : function(text) { 
    return text.match(/\s/).length; 
}

알 수없는 이유로 항상을 반환합니다 1. 위 진술의 문제점은 무엇입니까? 나는 이후 다음과 같은 문제를 해결했습니다.

numSpaces : function(text) { 
    return (text.split(/\s/).length -1); 
}

tl; dr : 일반 패턴 카운터

// THIS IS WHAT YOU NEED
const count = (str) => {
  const re = /YOUR_PATTERN_HERE/g
  return ((str || '').match(re) || []).length
}

여기에 도착한 사람들은 문자열에서 정규식 패턴의 발생 횟수를 계산하는 일반적인 방법을 찾고 있으며 0 발생이 발생해도 실패하지 않도록하려면이 코드가 필요합니다. 다음은 데모입니다.

/*
 *  Example
 */

const count = (str) => {
  const re = /[a-z]{3}/g
  return ((str || '').match(re) || []).length
}

const str1 = 'abc, def, ghi'
const str2 = 'ABC, DEF, GHI'

console.log(`'${str1}' has ${count(str1)} occurrences of pattern '/[a-z]{3}/g'`)
console.log(`'${str2}' has ${count(str2)} occurrences of pattern '/[a-z]{3}/g'`)

원래 답변

초기 코드의 문제는 전역 식별자 가 없다는 것입니다 .

>>> 'hi there how are you'.match(/\s/g).length;
4

g정규식 일부가 없으면 첫 번째 발생과 일치하고 거기서 중지됩니다.

또한 정규식은 연속 공백을 두 번 계산합니다.

>>> 'hi  there'.match(/\s/g).length;
2

바람직하지 않은 경우 다음을 수행 할 수 있습니다.

>>> 'hi  there'.match(/\s+/g).length;
1

이전 답변 에서 언급했듯이 RegExp.exec()모든 일치 항목을 반복하고 각 항목을 계산 하는 사용할 수 있습니다 . 전체적으로 사용하는 것보다 약 20 % 더 느리기 때문에 장점은 메모리에만 국한됩니다 String.match().

var re = /\s/g,
count = 0;

while (re.exec(text) !== null) {
    ++count;
}

return count;

(('a a a').match(/b/g) || []).length; // 0
(('a a a').match(/a/g) || []).length; // 3

https://stackoverflow.com/a/48195124/16777을 기반으로 하지만 실제로 결과가없는 경우에서 작동하도록 수정되었습니다.


('my string'.match(/\s/g) || []).length;


이것은 확실히 많은 함정이있는 것입니다. 나는 Paolo Bergantino의 대답으로 작업하고 있었고 그것에도 약간의 한계가 있음을 깨달았습니다. 날짜의 문자열 표현으로 작업하는 것이 주요 문제 중 일부를 빠르게 찾을 수있는 좋은 장소임을 알았습니다. 다음과 같은 입력 문자열로 시작합니다.'12-2-2019 5:1:48.670'

다음과 같이 Paolo의 기능을 설정합니다.

function count(re, str) {
    if (typeof re !== "string") {
        return 0;
    }
    re = (re === '.') ? ('\\' + re) : re;
    var cre = new RegExp(re, 'g');
    return ((str || '').match(cre) || []).length;
}

I wanted the regular expression to be passed in, so that the function is more reusable, secondly, I wanted the parameter to be a string, so that the client doesn't have to make the regex, but simply match on the string, like a standard string utility class method.

Now, here you can see that I'm dealing with issues with the input. With the following:

if (typeof re !== "string") {
    return 0;
}

I am ensuring that the input isn't anything like the literal 0, false, undefined, or null, none of which are strings. Since these literals are not in the input string, there should be no matches, but it should match '0', which is a string.

With the following:

re = (re === '.') ? ('\\' + re) : re;

I am dealing with the fact that the RegExp constructor will (I think, wrongly) interpret the string '.' as the all character matcher \.\

Finally, because I am using the RegExp constructor, I need to give it the global 'g' flag so that it counts all matches, not just the first one, similar to the suggestions in other posts.

I realise that this is an extremely late answer, but it might be helpful to someone stumbling along here. BTW here's the TypeScript version:

function count(re: string, str: string): number {
    if (typeof re !== 'string') {
        return 0;
    }
    re = (re === '.') ? ('\\' + re) : re;
    const cre = new RegExp(re, 'g');    
    return ((str || '').match(cre) || []).length;
}

how about like this

function isint(str){
    if(str.match(/\d/g).length==str.length){
        return true;
    }
    else {
         return false
    }
}

참고URL : https://stackoverflow.com/questions/1072765/count-number-of-matches-of-a-regex-in-javascript

반응형