-1

I am trying to use a specific regex to validate a user's first name on an HTML form.

I tested the regex with a regex tester, but the regex is not working here as a string in the pattern attribute.

What is the issue? Is there a possible solution?

<input
  name="firstName"
  pattern="^[\w'\-,.][^0-9_!¡?÷?¿\/\\+=@#$%ˆ&*(){}|~<>;:[\]]{2,}$"
  title="Your first name must be valid"
  type="text"
  placeholder="First Name"
  required
/>

About the rules, it's basically to only allow names. I'm not sure of all the rules, but it's words only, spaces are allowed, numbers are not allowed, and only certain characters are allowed, such as apostrophe ('), hyphens (-), etc.

Patrick Janser
  • 3,318
  • 1
  • 16
  • 18
Brendan
  • 834
  • 1
  • 9
  • 20
  • 1
    What are the validation rules? It's unclear to me what the expected behavior is. – Kosh Aug 18 '23 at 15:53
  • @Kosh It's basically to only allow names. I'm not sure of all the rules, but it's words only, spaces are allowed, numbers are not allowed, and only certain characters are allowed, such as apostrophe ('), dashes (-), etc. – Brendan Aug 18 '23 at 16:00
  • FYI you don't need `^` and `$` when using `pattern`. The pattern is automatically anchored. – Barmar Aug 18 '23 at 16:03
  • 1
    @Brendan, looks like your problem is that you don't know what you want exactly. Try to figure it out first please. – Kosh Aug 18 '23 at 16:06
  • Read about character classes, https://www.regular-expressions.info/charclass.html. That should be what you need. – user3783243 Aug 18 '23 at 16:20
  • Try switching the flavor to ECMAScript and turning the `v` flag on. You should then see where the problem is. – InSync Aug 18 '23 at 17:17
  • Does this answer your question? [Valid with the RegExp u flag, but not with the v flag](https://stackoverflow.com/questions/76285652/valid-with-the-regexp-u-flag-but-not-with-the-v-flag) – InSync Aug 18 '23 at 17:17
  • Not a fix but note that the [](https://html.spec.whatwg.org/dev/embedded-content.html#the-input-element) tag does not use and does not need a closing slash and never has in any HTML specification – Rob Aug 19 '23 at 07:05
  • @Rob: I don't think it's important, especially because [void elements](https://html.spec.whatwg.org/multipage/syntax.html#void-elements), including ``, are allowed to be self-closed with `/>`, just like a `
    ` or `
    ` tag depending on the [doctype](https://www.w3schools.com/tags/tag_doctype.asp). I think it will only be invalid with HTML 4.01. Now that we are often using HTML 5, it won't be a problem. It can just be some sugar for readability, make it more compatible with XML parsers, and perhaps also help some old color highlighting tools work better. But yes, `
    ` is bad!
    – Patrick Janser Aug 22 '23 at 15:21
  • @Brendan : I think the problem is due to the chars `|`, `{`, etc in your negative character class. *JavaScript* regex flavor seems to change and now they have to be escaped even in a character class. This is due to [new features with the **v** pattern flag](https://v8.dev/features/regexp-v-flag). See my answer for another kind of pattern. – Patrick Janser Aug 22 '23 at 15:43
  • @PatrickJanser It's only allowed for backwards compatibility but the fact remains that it is still unspecified for use. The slash does nothing, [it has no meaning](https://github.com/validator/validator/wiki/Markup-%C2%BB-Void-elements#trailing-slashes-in-void-element-start-tags-do-not-mark-the-start-tags-as-self-closing), and browsers are instructed to ignore it so it is pointless. If anything, [it causes harm](https://github.com/validator/validator/wiki/Markup-%C2%BB-Void-elements#trailing-slashes-directly-preceded-by-unquoted-attribute-values) and the W3C validator flags it. – Rob Aug 22 '23 at 18:43
  • @PatrickJanser And, as always it's best to follow the standard. Consider compatibility with XML opens a totally different can of worms that almost HTML would not work with. – Rob Aug 22 '23 at 18:45
  • @Rob: ok, I hear your point of view. I personally don't think that many people put URLs in `Big cat` without quotes and without a space between the value and the closing slash, but yes, let's stop using them. – Patrick Janser Aug 24 '23 at 07:00
  • @PatrickJanser It's not a point of view. It's the point blank standard specification. – Rob Aug 24 '23 at 07:12
  • @Rob: Ok, fine. I'll update my old bad habits and try to set all the good settings in the IDEs I use. I just did a test with the W3C HTML validator, and it validates, but prints an "info" in green, saying that there's no need to self-close a void element. Just to notice, it's not considered to be an error neither a warning. – Patrick Janser Aug 24 '23 at 08:14

1 Answers1

0

I think the issue can be due to the characters you declared in the character classes. According to some changes to the regex flavor in JavaScript, the u or v flag may be enabled (it seems to be hard-coded or automatically triggered and cannot be set manually) and this can cause problems in character classes. For example, [a-z|] has | which should now be escaped with \| also in a character class. You're using some in your pattern.

I would not use \w but replace it by \p{L} which is used to match any letter in any language. This will match "é" or "ÿ" and not only English letters without accents.

It's rather complicated to match all the correct cases, but this is what I can suggest:

^(?:\p{L}['´ \-]?)+(?<=[^\s\-'´])$

The idea is to accept an input starting with a letter and then followed by an optional space, hyphen or ' or ´, one or multiple times. To avoid finishing with a space or one of those chars, you can add a positive lookbehind just before the end of the pattern.

This will avoid accepting something like Jack- or Ooooh'.

The other advantage is that you can't accept Jean--Jaques or O''Neil.

form {
  margin: 1em;
  padding: 0;
  display: flex;
  column-gap: 1em;
}

input {
  padding: 0.25em .5em;
  border: 1px solid gray;
}

input[type="text"] {
  box-shadow: 1px 1px 4px inset rgba(0, 0, 0, 0.1);
}
input[type="text"]:focus {
  outline: 1px solid gray;
}

input[pattern]:focus:valid {
  border-color: green;
}

input[pattern]:focus:invalid {
  border-color: red;
}

input[type="submit"] {
  background-color: silver;
}

:focus-visible {
  outline: none;
}
<form action="#">
  <div class="form-element">
    <input
      name="firstName"
      pattern="^(?:\p{L}['´ \-]?)+(?<=[^\s\-'´])$"
      title="Your first name must be valid"
      type="text"
      placeholder="First Name"
      required
    />
  </div>
  <div class="form-element form-submit">
    <input type="submit" value="Submit" />
  </div>
</form>

You can also test the regex with examples and the explanation here: https://regex101.com/r/tmEsgX/2

Patrick Janser
  • 3,318
  • 1
  • 16
  • 18