Skip to content

Commit

Permalink
fix(utils): 특수 문자에 대한 개수와 공백에 대한 처리 추가 (#168)
Browse files Browse the repository at this point in the history
* fix(utils): 특수 문자에 대한 개수와 공백에 대한 처리 추가

* chore: console.log 제거

* refactor(utils): 함수 배치 수정 및 while 문 가독성 향상

* docs(utils): 중복 문자열에 대한 옵션 허용 문서화
  • Loading branch information
hoonloper authored May 27, 2024
1 parent 3bf54d0 commit 73a9f34
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 3 deletions.
4 changes: 4 additions & 0 deletions docs/docs/utils/string/countSubstringOccurrences.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ import { countSubstringOccurrences } from '@modern-kit/utils';
const str = 'apple banana apple grapes apple';
const count1 = countSubstringOccurrences(str, 'apple'); // 3
const count2 = countSubstringOccurrences(str, 'apple banana'); // 1

const duplicatedStr = 'aaaa'
const count3 = countSubstringOccurrences(duplicatedStr, 'aa'); // 2, double counting not allowed
const count4 = countSubstringOccurrences(duplicatedStr, 'aa', { overlap: true }); // 3, double counting allowed
```
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,20 @@ describe('countSubstringOccurrences', () => {
expect(countSubstringOccurrences(str2, '테스트')).toBe(4);
expect(countSubstringOccurrences(str2, '테스트용 문자열')).toBe(2);
});

it('should return 0 when either source or target is an empty string', () => {
expect(countSubstringOccurrences('', 'abc')).toBe(0);
expect(countSubstringOccurrences('abc', '')).toBe(0);
});

it('should return the correct count of occurrences', () => {
expect(countSubstringOccurrences('abc', 'abc')).toBe(1);
expect(countSubstringOccurrences('aaaa', 'aa', { overlap: true })).toBe(3);
expect(countSubstringOccurrences('banana', 'na')).toBe(2);
});

it('should handle special characters in the target string', () => {
expect(countSubstringOccurrences('a.b.c', '.')).toBe(2);
expect(countSubstringOccurrences('a(b)c(d)e', '(')).toBe(2);
});
});
39 changes: 36 additions & 3 deletions packages/utils/src/string/countSubstringOccurrences/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,39 @@
export const countSubstringOccurrences = (source: string, target: string) => {
const regex = new RegExp(target, 'g');
const matches = source.match(regex);
type Options = { overlap: boolean };

const escapeRegExp = (str: string): string => {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
};

const countAllowOverlap = (source: string, regex: RegExp) => {
let count = 0;
let match = regex.exec(source);

while (match !== null) {
count++;
regex.lastIndex = match.index + 1;

match = regex.exec(source);
}

return count;
};

const countExceptOverlap = (source: string, regex: RegExp) => {
const matches = source.match(regex);
return matches ? matches.length : 0;
};

export const countSubstringOccurrences = (
source: string,
target: string,
options: Options = { overlap: false }
): number => {
if (target === '') return 0;

const escapedTarget = escapeRegExp(target);
const regex = new RegExp(escapedTarget, 'g');

return options.overlap
? countAllowOverlap(source, regex)
: countExceptOverlap(source, regex);
};

0 comments on commit 73a9f34

Please sign in to comment.