/ src / data / string / pattern.js
pattern.js
 1  const ANY_CHAR = '[\\s\\S]'
 2  export const GLOB = { ignoreCase: false, single: '?', arbitrary: '*' }
 3  export const LIKE = { ignoreCase: true, single: '_', arbitrary: '%' }
 4  
 5  /**
 6   *
 7   * @param {string} source
 8   * @param {object} options
 9   * @param {boolean} options.ignoreCase
10   * @param {string} options.single
11   * @param {string} options.arbitrary
12   *
13   * @returns
14   */
15  export const compile = (source, { ignoreCase, single, arbitrary }) => {
16    const flags = ignoreCase ? 'i' : ''
17    let pattern = ''
18    let escaping = false
19    for (const char of source) {
20      switch (char) {
21        case single: {
22          pattern = escaping ? `${pattern}${char}` : `${pattern}${ANY_CHAR}`
23          escaping = false
24          break
25        }
26        case arbitrary: {
27          pattern = escaping ? `${pattern}${char}` : `${pattern}${ANY_CHAR}*`
28          escaping = false
29          break
30        }
31        case '\\': {
32          pattern = `${pattern}${char}`
33          escaping = !escaping
34          break
35        }
36        case '/':
37        case '*':
38        case '$':
39        case '^':
40        case '+':
41        case '.':
42        case ',':
43        case '(':
44        case ')':
45        case '<':
46        case '=':
47        case '!':
48        case '[':
49        case ']':
50        case '}':
51        case '{':
52        case '|': {
53          pattern = escaping ? `${pattern}${char}` : `${pattern}\\${char}`
54          escaping = false
55          break
56        }
57        default:
58          pattern = `${pattern}${char}`
59          break
60      }
61    }
62  
63    return new RegExp(`^${pattern}$`, flags)
64  }