最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to check valid regex on select - Stack Overflow

programmeradmin3浏览0评论

I have the following code

    const SelectSizesDemo = () => {
      const pattern = new RegExp(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i);
      const errorMsg = "please provide valid email!";

      const [emailArr, setEmailArr] = useState([]);
      const [error, setError] = useState(false);

      return (
        <div>
          <Select
            style={{ width: "90%" }}
            mode="tags"
            onChange={(e) => setEmailArr(e)}
          ></Select>
          {error && errorMsg}
        </div>
      );
    };

I am trying to do the following. The user should input some email, if its email is valid with my pattern then I should add it to my emailArr, if it's not correct then I should show the error message errorMsg, clear from the selected items and not allow the user to add it to the array.

In this code, I successfully can add any string to my array, so I want your help to understand how can I check that string with my pattern.

Please help me to resolve this problem.

Thanks

I have the following code

    const SelectSizesDemo = () => {
      const pattern = new RegExp(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i);
      const errorMsg = "please provide valid email!";

      const [emailArr, setEmailArr] = useState([]);
      const [error, setError] = useState(false);

      return (
        <div>
          <Select
            style={{ width: "90%" }}
            mode="tags"
            onChange={(e) => setEmailArr(e)}
          ></Select>
          {error && errorMsg}
        </div>
      );
    };

I am trying to do the following. The user should input some email, if its email is valid with my pattern then I should add it to my emailArr, if it's not correct then I should show the error message errorMsg, clear from the selected items and not allow the user to add it to the array.

In this code, I successfully can add any string to my array, so I want your help to understand how can I check that string with my pattern.

Please help me to resolve this problem.

Thanks

Share Improve this question edited Oct 7, 2022 at 14:01 someone asked Oct 7, 2022 at 11:49 someonesomeone 6911 gold badge6 silver badges26 bronze badges 2
  • updated code but not working correctly – someone Commented Oct 7, 2022 at 14:03
  • So do you actually have a "problem" or are you just unsure of how to implement this? – code Commented Oct 11, 2022 at 4:34
Add a ment  | 

6 Answers 6

Reset to default 6 +200

I've worked on your updated code and figured out what was the problem.

Here is my full code before I start explaining to you what I changed.

Explanations:

  • So first, in order to make the select always have the values of the emailArr, you need to bind it to that state with the value attribute. This way, any change in the emailArr state will be applied to the select values too.

    So simply you add: value = {emailArr} in the select.

  • Second, in the onChange event you get an array in the e object which is the array of the current values that are in the select field. So in order to test the value, you need to check the validation of the current value that was inserted to that array, which is the last one in it.

    In your code you check the validation of the entire array which cause it to not work correctly:

    Your code:

      onChange={(e) => {
          if (pattern.test(e)) {
            setEmailArr(e);
          } else {
            setError(true);
          }
        }}
    

    Should be:

     onChange={(e) => {
          if (e.length !== 0) {//First check if the array is not empty 
    
            const value = e[e.length - 1]; //get the last(current) value from the array
            if (pattern.test(value)) {
              setEmailArr(e);
              setError(false);
            } else {
              setError(true);
            }
    
          }
        }}
    

    So Here, I first check if the e array is not empty. Because if I check the last value of an empty array it will be undefined - which is false, and this will go to the else block and set the error to true, which is wrong. So that's why I start these checks only if there's something to check in the array.

    Next, I check the current value, if it's valid you update the state (which need to be bined with the select) to the new array with the new value, otherwise - it won't. And by the way, I added setError(false) in case that there was an invalid try before and I want to hide the previous error now.

And a note: The emails you enter in the select must be capitalized in order to match the pattern you chose. If you don't want it then just change it to this pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/g.

Result:

So that's it. I hope everything was clear, and please check the full code.

You can validate string with regex using this code :

onChange={(e) => {
              if(pattern.test(e.target.value)){
              setEmailArr(e.target.value)
              }else{
                setError(true)
              }
 }}

The goal of this solution is to tell antd to use "our" email list instead of using "their" internal list.

onChange is called when a new element is added to the list. Check the last element and see if it's valid and then update your internal email list with antd's email list.

I use Set which automatically handles duplicates, but you could do this with only lists if you prefer.

Whenever the emailSet changes I update the email list alphabetically, but you don't need to do this if you don't want. A simple [...emailSet] is sufficient.

onDeselect seems to be called when the last element is removed, so I just clear the rest of the elements.

const SelectSizesDemo = () => {
  const pattern = new RegExp(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i);

  const [error, setError] = useState(false);
  const [emailSet, setEmailSet] = useState(new Set());
  const emails = useMemo(() => {
    return [...emailSet].sort((a, b) => a.localeCompare(b));
  }, [emailSet]);

  const addEmail = (e) => {
    if(e.length === 0) {
      return;
    }
    const email = e[e.length - 1];
    if (!pattern.test(email)) {
      setError(errorMsg);
      return;
    }
    setEmailSet(new Set(e))
    if (error) {
      setError(false);
    }
  };

  const clearAll = () => {
    setEmailSet(new Set([]));
  };

  return (
    <div>
      <Select
        style={{ width: "90%" }}
        mode="tags"
        onChange={addEmail}
        onDeselect={clearAll}
        value={emails}
      ></Select>
      {error && errorMsg}
    </div>
  );
};

Full solution here.

As per my understanding, You want to test the email based on the input value enter by the user and if its a valid email as per the pattern you want to store that in an array else you want to show the error message. If Yes, Here you go :

To validate an email, You can use the RegEx test() method which executes a search for a match between a regular expression and a specified string. Returns true if the email is valid else returns false.

Live Demo :

const {useState, useCallback} = React;

function Example() {
    const [emailArr, setEmailArr] = useState([]);
    const [error, setError] = useState(false);
    
    function isValidEmail(email) {
      const pattern = new RegExp(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i);
      return pattern.test(email);
    }
    
    const handleEmailValidation = event => {
      const errorMsg = "please provide valid email!";

      if (!isValidEmail(event.target.value)) {
        setError(errorMsg);
      } else {
        setEmailArr(oldArray => [...oldArray, event.target.value]);
        setError(null);
      }
    };
    
    return (
        <div>
          <input
            id="email"
            name="email"
            onChange={handleEmailValidation}
          />
          {error && <span class="error">{error}</span>}
          
          <div>{emailArr.map(entry =>
            <div>{entry}</div>
          )}
          </div>
        </div>
    );
}

ReactDOM.render(
    <Example />,
    document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>

As answered by Moein, pattern.test(string) is a valid way of checking if the user's input string matches your regex pattern.

Alternatively, you can use String.match(regex) to get an array of matches or null. This can still be used to evaluate truthiness.

Comparison was discussed here: regex.test V.S. string.match to know if a string matches a regular expression

you just need to use regex method as pattern.test(yourString)

发布评论

评论列表(0)

  1. 暂无评论