В наборе RegExp символ дефис-минус (ваша стандартная клавиатура) обозначает диапазон кодов символов между двумя символами, которые он разделяет. Исключения составляют случаи, когда он экранирован (\-
) или когда он не разделяет два символа, поскольку он является либо последним символом класса, либо первым символом (после дополнительной каретки, которая инвертирует класс).
Три примера диапазонов символов: простой пример, расширенный пример и ошибка:
[a-z]
довольно просто, потому что работает так, как мы ожидаем, хотя на самом деле это происходит потому, что коды символов оказываются последовательными. Другой способ написать это [\x61-\x7a]
[!-~]
не совсем прост, по крайней мере, пока вы не посмотрите на карту символов и не узнаете, что !
- это первый печатный символ ASCII, а ~
- последний (из «нижнего ASCII»), поэтому это способ сказать "все печатаемые нижние символы ASCII", и это эквивалент [\x21-\x7e]
[A-z]
имеет переключаемый корпус. Вам может не понравиться тот факт, что в этом диапазоне допустимо шесть не буквенных символов (то есть [\x41-\x7a]
)
Теперь давайте проверим ваше регулярное выражение /[\w-+]/u
Regex101 имеет более информативную ошибку: «Вы не можете создать диапазон с краткими escape-последовательностями»
Так как \w
сам по себе не является символом (а скорее набором символов), примыкающая черточка должна восприниматься буквально или же как ошибка. Когда вы вызываете его с флагом /u
для запуска fullUnicode
, вы входите в более строгий режим и, следовательно, получаете ошибку.
Ошибка, которую я получаю от "foo".match(/[\w-+]/u)
в Firefox 64.0:
SyntaxError: символьный escape нельзя использовать в диапазоне классов в регулярном выражении
Это немного более информативно, чем ошибка, которую вы получили, поскольку она фактически говорит вам, что проблема в побеге (хотя и не в том, почему это проблема).
Согласно ECMAScript 2015's RegExBuiltinExec()
логика :
- Если fullUnicode равен true , то
- e - это индекс в списке символов Input , полученный из S , которому соответствует matcher . Пусть eUTF будет наименьшим индексом в S , который соответствует символу в элементе e из Input . Если e больше или равно длине Input , тогда eUTF - это количество единиц кода в S.
- Пусть e будет eUTF .
Кажется, это явно строит свою собственную логику разбора диапазона.
Решение состоит в том, чтобы либо убежать от вашего дефис-минуса, либо поставить его последним (или первым):
/[\w\-+]/u
или /[\w+-]/u
или /[-\w+]/u
. Лично я всегда ставлю это последним.