错误无效的正则表达式转义,同时允许特殊字符选项

问题描述 投票:0回答:2

我正在尝试使用我的 TypeScript 项目中的一个函数来验证一个字符串以确保它只包含某些字符。该函数将一个字符串和一个选项对象作为参数,选项指定允许哪些字符。

函数如下:

/**
 * Validates a string to ensure it only contains allowed characters.
 * @param {string} name - The string to validate.
 * @param {Object} [options] - The options to use for validation.
 * @param {boolean} [options.allowNumbers=false] - Whether to allow numbers.
 * @param {boolean} [options.allowSpecialCharacters=false] - Whether to allow special characters.
 * @param {boolean} [options.allowSpaces=false] - Whether to allow spaces.
 * @param {boolean} [options.allowUnderscores=false] - Whether to allow underscores.
 * @param {boolean} [options.allowDashes=false] - Whether to allow dashes.
 * @param {boolean} [options.allowPunctuation=false] - Whether to allow punctuation.
 * @param {boolean} [options.allowCyrillic=false] - Whether to allow Cyrillic characters.
 * @param {boolean} [options.allowNonLatin=false] - Whether to allow non-Latin characters.
 * @returns {boolean} Whether the string is valid or not.
 */
interface IValidateNameOptions {
  allowNumbers?: boolean;
  allowSpecialCharacters?: boolean;
  allowSpaces?: boolean;
  allowUnderscores?: boolean;
  allowDashes?: boolean;
  allowPunctuation?: boolean;
  allowCyrillic?: boolean;
  allowNonLatin?: boolean;
}

interface IValidateName {
  (name: string, options?: IValidateNameOptions): boolean;
}

export const validateName: IValidateName = (
  name,
  options = {
    allowNumbers: false,
    allowSpecialCharacters: false,
    allowSpaces: false,
    allowUnderscores: false,
    allowDashes: false,
    allowPunctuation: false,
    allowCyrillic: false,
    allowNonLatin: false,
  },
) => {
  let regexStr = `^[a-zA-Z`;

  if (options.allowNonLatin) {
    regexStr += `\\p{L}`;
  }
  if (options.allowNumbers) {
    regexStr += `0-9`;
  }
  if (options.allowSpecialCharacters) {
    regexStr += `\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)\\-\\_\\=\\+\\[\\]\\{\\}\\|\\\\\\;\\:\\'\\,\\.\\/\\<\\>\\?`;
  }
  if (options.allowSpaces) {
    regexStr += `\\s`;
  }
  if (options.allowUnderscores) {
    regexStr += `\\_`;
  }
  if (options.allowDashes) {
    regexStr += `\\-`;
  }
  if (options.allowPunctuation) {
    regexStr += `\\p{P}`;
  }
  if (options.allowCyrillic) {
    regexStr += `\\p{Cyrillic}`;
  }
  regexStr += `]+$`;

  const regex = new RegExp(regexStr, 'u');
  return regex.test(name);
};

这里是笑话测试:

it('should return true when name is valid and allowSpecialCharacters is true', () => {
  expect(validateName('Deri!', { allowSpecialCharacters: true })).toBe(true);
});

这里是错误测试:

 FAIL  src/tests/validateName.test.ts
  ✓ should return true when name is valid (3 ms)
  ✓ should return false when name is invalid (6 ms)
  ✕ should return true when name is valid and allowSpecialCharacters is true (2 ms)

  ● should return true when name is valid and allowSpecialCharacters is true

    SyntaxError: Invalid regular expression: /^[a-zA-Z\!\@\#\$\%\^\&\*\(\)\-\_\=\+\[\]\{\}\|\\\;\:\'\,\.\/\<\>\?]+$/: Invalid escape
        at new RegExp (<anonymous>)

      69 |   regexStr += `]+$`;
      70 |
    > 71 |   const regex = new RegExp(regexStr, 'u');
         |                 ^
      72 |   return regex.test(name);
      73 | };
      74 |

      at validateName (src/lib/validateName.ts:71:17)
      at Object.<anonymous> (src/tests/validateName.test.ts:41:22)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 2 passed, 3 total
Snapshots:   0 total
Time:        1.536 s
Ran all test suites.

然而,当我尝试使用该函数时,即使我已经转义了所有特殊字符,我仍然收到“无效转义”错误。谁能告诉我我做错了什么?谢谢!

答案解释和正确的RegExp代码

javascript regex typescript
2个回答
0
投票

如果你在浏览器中运行它,你会得到相同的

const reg1 = /^[a-zA-Z\!\@\#\$\%\^\&\*\(\)\-\_\=\+\[\]\{\}\|\\\;\:\'\,\.\/\<\>\?]+$/u
console.log(reg1)

问题是你指定了 - /u 这意味着它期望反斜杠字符像这样以 u 开头

这有效:

// \u003a === :
const reg = /\u003a/u
const matched = ' :'.match(reg)
console.log(matched)

0
投票

你的一些转义字符在 JavaScript 中不是特殊字符。当您使用带有

u
标志的 Unicode 模式时,您不能“以防万一”转义非特殊字符。这是禁止的,以确保将来添加特殊转义序列的可能性。

比较:

console.log(/:/); // No errors.
console.log(/\:/); // No errors as there is no u flag.
console.log(/\:/u); // Throws error.

所以你只需要逃离

[ \ ^ $ . | ? * + ( )
,或者更不用说在里面
[]
.

参见https://javascript.info/regexp-escapinghttps://javascript.info/regexp-character-sets-and-ranges#escaping-in-

© www.soinside.com 2019 - 2024. All rights reserved.