skip to Main Content

Issue Using Regex Pattern in HTML Pattern Attribute

I’m encountering an issue where a regex pattern that works correctly with the .test() method in JavaScript is not functioning as expected when used within an HTML pattern attribute. Here’s the regex pattern:

/^(?:[A-Z][a-z]*|((?:[A-Za-z]*?)))(?:[-s()]*(?:[A-Z][a-z]*|((?:[A-Za-z]*?))))*$/

When I try to use this pattern in the HTML pattern attribute, like so:

<input type="text" pattern="^(?:[A-Z][a-z]*|((?:[A-Za-z]*?)))(?:[-s()]*(?:[A-Z][a-z]*|((?:[A-Za-z]*?))))*$">

I encounter the error:

Pattern attribute value /^(?:[A-Z][a-z]*|((?:[A-Za-z]*?)))(?:[-s()]*(?:[A-Z][a-z]*|((?:[A-Za-z]*?))))*$/ is not a valid regular expression: Uncaught SyntaxError: Invalid regular expression: //^(?:[A-Z][a-z]*|((?:[A-Za-z]*?)))(?:[-s()]*(?:[A-Z][a-z]*|((?:[A-Za-z]*?))))*$//v: Invalid character in character class

Here are some inputs along with the expected results:

Input                               | Expected Result
---------------------------------------------------------
John-Doe                            | true
John-Doe-Smith                      | true
John-Doe-Smith (AB)                 | true
John (AB) Doe-Smith                 | true
John-Doe (AB) Smith                 | true
John (AB) Doe-Smith (C)             | true
John-Doe (AB) (C) Smith             | true
John-Doe (ABc) (C) Smith            | true
John (AB) Doe-Smith (C) (D)         | true
John (AB) Doe-Smith (C) (d)         | false
John (ABc) Doe-Smith                | true
John Doe-Smith (ab)                 | false
John-Doe (ABc) (D)                  | true
John (AB) (C) Doe-Smith             | true
John-Doe (AB) (c) Smith             | false
John (AB) (C) (D) Doe-Smith         | true
John-Doe (AB) (C) (d) Smith         | false
John-Doe (ABc) (D) (e) Smith        | false
John (ABc) (D) (E) Doe-Smith        | true
John-Doe (ABc) (D) (E) (F) Smith    | true

I’m unsure why this error occurs, especially since the regex works as expected in JavaScript. Can anyone provide insight into why this regex pattern is not accepted in the HTML pattern attribute?

Thank you in advance for any help or suggestions!

2

Answers


  1. Using regex.test() by addEventListener()

    Inside the event listener, the current value of the input field is tested against the regular expression using regex.test(inputText.value).

    If the input value matches the regular expression (i.e., it is valid), the condition inside the if statement is true. Otherwise, it is false.

    const regex = /^(?:[A-Z][a-z]*|((?:[A-Za-z]*?)))(?:[-s()]*(?:[A-Z][a-z]*|((?:[A-Za-z]*?))))*$/;
    
    inputText.addEventListener('input', function() {
        if (regex.test(inputText.value)) {
            // valid
        } else {
            // invalid
        }
    });
    

    Demo

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Input Validator</title>
        <style>
            .validity {
                display: inline-block;
                width: 24px;
                height: 24px;
                vertical-align: middle;
            }
            .validity.valid {
                background: url('https://www.freeiconspng.com/uploads/actions-ok-icon-26.png') no-repeat center center;
                background-size: contain;
            }
            .validity.invalid {
                background: url('https://www.freeiconspng.com/uploads/x-png-22.png') no-repeat center center;
                background-size: contain;
            }
        </style>
    </head>
    <body>
        <h2>Input Validator</h2>
        <form id="testForm">
            <label for="inputText">Enter a string:</label>
            <input type="text" id="inputText" name="inputText" required>
            <span class="validity" id="validityIcon"></span>
        </form>
    
        <script>
            const inputText = document.getElementById('inputText');
            const validityIcon = document.getElementById('validityIcon');
            const regex = /^(?:[A-Z][a-z]*|((?:[A-Za-z]*?)))(?:[-s()]*(?:[A-Z][a-z]*|((?:[A-Za-z]*?))))*$/;
    
            inputText.addEventListener('input', function() {
                if (regex.test(inputText.value)) {
                    validityIcon.classList.remove('invalid');
                    validityIcon.classList.add('valid');
                } else {
                    validityIcon.classList.remove('valid');
                    validityIcon.classList.add('invalid');
                }
            });
        </script>
    </body>
    </html>
    

    regex visualization

    enter image description here

    Result

    enter image description here

    Login or Signup to reply.
  2. The error message you’re seeing indicates that there’s a problem with the regular expression (regex) pattern you’re using in your input field. The pattern you’re using is:

    ^(?:[A-Z][a-z]*|((?:[A-Za-z]*?)))(?:[-s()]*(?:[A-Z][a-z]*|((?:[A-Za-z]*?))))*$

    This pattern seems to be quite complex and might contain some unnecessary parts. The error is likely due to the use of the ? quantifier after a non-capturing group (?:[A-Za-z]*?). The ? makes the preceding token in the regular expression optional. In this case, it’s making the non-capturing group optional, which is not necessary because the * already makes it optional. A simplified version of your regex that should work might look like this:

    <input type="text" pattern="^(?:[A-Z][a-z]*|([A-Za-z]*))(?:[-s()]*[A-Z][a-z]*|([A-Za-z]*))*$"/>

    This pattern will match strings that start with an uppercase letter followed by zero or more lowercase letters, or a group of any case letters enclosed in parentheses. This can be followed by zero or more groups that start with a hyphen, space, or parentheses, followed by an uppercase letter and zero or more lowercase letters, or a group of any case letters enclosed in parentheses. The string must end with the end of a group.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search