\S
will select all non "whitespace" characters equivalent to [ \t\n\r\f\v]
_
will select "_" because we negate it when using the \W
and need to add it back in The most simple and shortest way to accomplish this:
/[^\p{L}\d\s@#]/u
[^...]
Match a single character not present in the list below
\p{L}
=> matches any kind of letter from any language
\d
=> matches a digit zero through nine
\s
=> matches any kind of invisible character
@#
=> @
and #
characters
Don't forget to pass the u
(unicode) flag.
A simple way to achieve this is the negative set [^\w\s]. This essentially catches:
For some reason [\W\S] does not work the same way, it doesn't do any filtering. A comment by Zael on one of the answers provides something of an explanation.
// The string must contain at least one special character, escaping reserved RegEx characters to avoid conflictconst hasSpecial = password => {const specialReg = new RegExp('^(?=.*[!@#$%^&*"\\[\\]\\{\\}<>/\\(\\)=\\\\\\-_´+`~\\:;,\\.€\\|])',);return specialReg.test(password);};
to build upon @jeff-hillman answer, this is the complete version
/[\\@#$-/:-?{-~!"^_`\[\]]/
Tests
function noSpecialChars(str) {const match = str.match(/[\\@#$-/:-?{-~!"^_`\[\]]/)if (!match) returnthrow new Error("got unsupported characters: " + match[0])}// prettier-ignoreconst symbols = ["!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "_", "+", "=", ".", ":", ";", "|","~","`","{","}","[","]","\"","'","<",">","?","/", "\\"]symbols.forEach((s) => {it(`validates no symbol ${s}`, async () => {expect(() => {noSpecialChars(s)}).toThrow();})})
How about (?=\W_)(?=\S).
? It checks that the character matched by the .
is not a word character (however _
is allowed) and that it's not whitespace.
Note: as @Casimir et Hippolyte pointed out in another comment, this will also match characters like é and such. If you don't expect such characters then this is a working solution.