Skip to content

Commit

Permalink
feat(regexp): 新增 emoji, email
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed May 27, 2023
1 parent a8f8fcc commit 59e0896
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 11 deletions.
28 changes: 19 additions & 9 deletions src/regexp/RegExpBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
export interface RegExpBuilderOptions {
/** 基础正则表达式 */
baseRegExp: RegExp
}

export interface RegExpBuilderBuildOptions {
/** `g` */
global?: boolean
/** `^...$` */
exact?: boolean
/** `...+` */
repeat?: boolean
}

export class RegExpBuilder {
Expand All @@ -15,15 +20,20 @@ export class RegExpBuilder {
}

build(options?: RegExpBuilderBuildOptions): RegExp {
const regExp = new RegExp(
options?.exact
? `^${this.options.baseRegExp.source}$`
: this.options.baseRegExp.source,
this.options.baseRegExp.flags +
(options?.global && this.options.baseRegExp.flags.indexOf('g') === -1
? 'g'
: ''),
)
let regExpSource = `(${this.options.baseRegExp.source})`
if (options?.repeat) {
regExpSource = `${regExpSource}+`
}
if (options?.exact) {
regExpSource = `^${regExpSource}$`
}

let regExpFlags = this.options.baseRegExp.flags
if (options?.global && this.options.baseRegExp.flags.indexOf('g') === -1) {
regExpFlags = `${regExpFlags}g`
}

const regExp = new RegExp(regExpSource, regExpFlags)
return regExp
}
}
10 changes: 10 additions & 0 deletions src/regexp/emailRegExpBuilder.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { emailRegExpBuilder } from './emailRegExpBuilder'

describe('emojiRegExpBuilder', () => {
test('test', () => {
expect(emailRegExpBuilder.build().test('hello@gmail.com')).toBeTrue()
expect(emailRegExpBuilder.build().test('hello+1@gmail.com')).toBeTrue()
expect(emailRegExpBuilder.build().test('hello.x@gmail.com')).toBeTrue()
expect(emailRegExpBuilder.build().test('gmail.com')).toBeFalse()
})
})
5 changes: 3 additions & 2 deletions src/regexp/emailRegExpBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { RegExpBuilder } from './RegExpBuilder'

// https://github.com/sindresorhus/email-regex/blob/main/index.js
const baseRegExp = /[^.\s@:](?:[^\s@:]*[^\s@:.])?@[^.\s@]+(?:\.[^.\s@]+)*/
// https://github.com/colinhacks/zod/blob/master/src/types.ts#LL560C19-L560C19
const baseRegExp =
/([A-Z0-9_+-]+\.?)*[A-Z0-9_+-]@([A-Z0-9][A-Z0-9-]*\.)+[A-Z]{2,}/i

export const emailRegExpBuilder = new RegExpBuilder({
baseRegExp: baseRegExp,
Expand Down
124 changes: 124 additions & 0 deletions src/regexp/emojiRegExpBuilder.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { emojiRegExpBuilder } from './emojiRegExpBuilder'

describe('emojiRegExpBuilder', () => {
test('test', () => {
expect(emojiRegExpBuilder.build().test('😌')).toBeTrue()
expect(emojiRegExpBuilder.build().test('👪')).toBeTrue()
expect(emojiRegExpBuilder.build().test('👪a')).toBeTrue()
expect(emojiRegExpBuilder.build().test('abc')).toBeFalse()
expect(emojiRegExpBuilder.build().test('😌👪')).toBeTrue()
})

test('test-exact', () => {
expect(emojiRegExpBuilder.build({ exact: true }).test('😌')).toBeTrue()
expect(emojiRegExpBuilder.build({ exact: true }).test('👪')).toBeTrue()
expect(emojiRegExpBuilder.build({ exact: true }).test('👪a')).toBeFalse()
expect(emojiRegExpBuilder.build({ exact: true }).test('abc')).toBeFalse()
expect(emojiRegExpBuilder.build({ exact: true }).test('😌👪')).toBeFalse()
})

test('test-exact-repeat', () => {
expect(
emojiRegExpBuilder.build({ exact: true, repeat: true }).test('😌'),
).toBeTrue()
expect(
emojiRegExpBuilder.build({ exact: true, repeat: true }).test('👪'),
).toBeTrue()
expect(
emojiRegExpBuilder.build({ exact: true, repeat: true }).test('👪a'),
).toBeFalse()
expect(
emojiRegExpBuilder.build({ exact: true, repeat: true }).test('abc'),
).toBeFalse()
expect(
emojiRegExpBuilder.build({ exact: true, repeat: true }).test('😌👪'),
).toBeTrue()
})

test('match', () => {
expect('😌'.match(emojiRegExpBuilder.build())![0]).toBe('😌')
expect('👪'.match(emojiRegExpBuilder.build())![0]).toBe('👪')
expect('👪a'.match(emojiRegExpBuilder.build())![0]).toBe('👪')
expect('abc'.match(emojiRegExpBuilder.build())).toBeNull()
expect('😌👪'.match(emojiRegExpBuilder.build())![0]).toBe('😌')
})

test('match-global', () => {
expect(
[...'😌'.matchAll(emojiRegExpBuilder.build({ global: true }))].map(
item => item[0],
),
).toEqual(['😌'])
expect(
[...'👪'.matchAll(emojiRegExpBuilder.build({ global: true }))].map(
item => item[0],
),
).toEqual(['👪'])
expect(
[...'👪a'.matchAll(emojiRegExpBuilder.build({ global: true }))].map(
item => item[0],
),
).toEqual(['👪'])
expect(
[...'abc'.matchAll(emojiRegExpBuilder.build({ global: true }))].map(
item => item[0],
),
).toEqual([])
expect(
[...'😌👪'.matchAll(emojiRegExpBuilder.build({ global: true }))].map(
item => item[0],
),
).toEqual(['😌', '👪'])
})

test('match-global-repeat', () => {
expect(
[
...'😌'.matchAll(
emojiRegExpBuilder.build({ global: true, repeat: true }),
),
].map(item => item[0]),
).toEqual(['😌'])
expect(
[
...'👪'.matchAll(
emojiRegExpBuilder.build({ global: true, repeat: true }),
),
].map(item => item[0]),
).toEqual(['👪'])
expect(
[
...'👪a'.matchAll(
emojiRegExpBuilder.build({ global: true, repeat: true }),
),
].map(item => item[0]),
).toEqual(['👪'])
expect(
[
...'abc'.matchAll(
emojiRegExpBuilder.build({ global: true, repeat: true }),
),
].map(item => item[0]),
).toEqual([])
expect(
[
...'😌👪'.matchAll(
emojiRegExpBuilder.build({ global: true, repeat: true }),
),
].map(item => item[0]),
).toEqual(['😌👪'])
})

test('getBaseRegExp', () => {
expect(
new RegExp(`(${emojiRegExpBuilder.getBaseRegExp().source})[A-Z]`).test(
'😌',
),
).toBeFalse()
expect(
new RegExp(`(${emojiRegExpBuilder.getBaseRegExp().source})[A-Z]`).test(
'😌X',
),
).toBeTrue()
})
})

0 comments on commit 59e0896

Please sign in to comment.