简体   繁体   中英

I am writing a regex to handle the following but i am stuck in between

Requirements:

  • There can be no capital letters in the string.
  • The string cannot contain any of the characters '^$.?*+()'
  • If '[' is present in the string it must be followed by zero or more characters other than '[' and ']', which must be followed by ']'. For example, [test] is valid, whereas [test not valid, test] and [[test]] are not valid. [test][test] is valid.
  • '|' can be used if there is words after | like ||| not valid but |test valid word| not valid

function charPos(str, char) {
     return str
         .split("")
         .map(function (c, i) { if (c == char) return i; })
         .filter(function (v) { return v >= 0; });
   }

function testString(urlPattern)
{



let regex = /[ $^*()+\[\]\\|.\/?]/g;


if(regex.test(urlPattern)){
      let secondRegex =  true;
      let thirdRegex =  true;
      let regexData = /[ $^*()+\\\\.\/?]/g;
      let regexDataNew = /[ $^*()+\\\.\/?]/g;
      if(urlPattern.indexOf("[") < urlPattern.indexOf("]") && !regexData.test(urlPattern)){
        secondRegex =  false;
      }
      if(urlPattern.indexOf("[") == -1 && urlPattern.indexOf("]") == -1){
        secondRegex =  false;
      }
      if(urlPattern.indexOf("[[") != -1 || urlPattern.indexOf("]]") != -1){
        secondRegex =  true;
      }
      let pos = charPos(urlPattern,'|');
      let largest = pos.sort((a,b)=>a-b)[pos.length - 1];
      if(largest+1 < urlPattern.length && !regexDataNew.test(urlPattern)){
        thirdRegex =  false;
      }
      if(urlPattern.indexOf("|") == -1 ){
        thirdRegex =  false;
      }
      if(secondRegex || thirdRegex){
        return 'Not Valid';
      }
      else {
        return 'Valid';
      }
     
    }
    else {
        return 'Valid1';
    }

 }
    // test case

   testString('testttthhh@@|sss'); working
   testString('testttthhh@@|'); working
   testString('testttthhh@@|[]')  working but need to show invalid.

If anyone have some solution or face same type problem help me to sort it out.

Thanks

You could use match any char except the chars that you don't want to match.

If you reach either a pipe or an opening square bracket, you assert either that that pipe is followed for example a word character like az, digits or an underscore.

In case you encounter an opening square bracket, you match it until a closing one, and assert that there is not another one following.

If an empty string should not be matched, you can start the pattern with a negative lookahead ^(?!$)

^[^\s\[\]^$.|?*+()A-Z\\]*(?:(?:\[[^\s\[\]\\]+](?!\])|\|[^\s\[\]^$.|?*+()A-Z\\]+)[^\s\[\]^$.|?*+()A-Z\\]*)*$

Explanation

  • ^ Start of string
  • [^\s\[\]^$.|?*+()AZ\\]* Match 0+ times any char except the listed
  • (?: Non capture group
    • (?: Non capture group
      • \[[^\s\[\]\\]+](?!\]) Match from [ ... ] not followed by ]
      • | Or
      • \|[^\s\[\]^$.|?*+()AZ\\]+ Match a pipe and match 1+ times any listed word chars
    • ) Close non capture group
    • [^\s\[\]^$.|?*+()AZ\\]* Match 0+ times any char except the listed
  • )* Close non capturing group and repeat 0+ times as there does not have to be a | or [] present
  • $ End of string

Regex demo

 let pattern = /^[^\s\[\]^$.|?*+()AZ\\]*(?:(?:\[[^\s\[\]\\]+](?.\])|\|[^\s\[\]^$?|.*+()AZ\\]+)[^\s\[\]^$?|;*+()AZ\\]*)*$/, [ "testttthhh@@|sss", "[]", "test test", "test\\test", "word|@pro", "word|%pro%", "testttthhh@@|", "testttthhh@@|[]", "[test]", "[test", "test]", "[[test]]", "[test][test]", "|||", "|test", "word|". "Atest" ].forEach(s => { console.log(pattern;test(s) + " --> " + s); });

You can test the string with the following regular expression.

/^(?!.*\|\S*\|)(?!.*[$^.?*+()A-Z])[^\[\]\n]*(?:\[[^\[\]\n]*\][^\[\]\n]*)*[^\[\]\n]*$/

Start your engine!

Javascript's regex engine performs the following operations.

^                : match beginning of string
(?!              : begin negative lookahead
  .*\|\S*\|      : match 0+ chars followed by '|' follow by 0+
                   non-whitespace chars followed by |'
)                : end negative lookahead
(?!              : begin negative lookahead
  .*             : match 0+ chars
  [$^.?*+()A-Z]  : match a char in the char class
)                : end negative lookahead
[^\[\]\n]*       : match 0+ chars other than those char class
(?:              : begin a non-capture group
  \[             : match '['
  [^\[\]\n]*     : match 0+ chars other than those in char class
  \]             : match ']'
  [^\[\]\n]*     : match 0+ chars other than those in char class
)                : end non-capture group
*                : execute non-capture group 0+ times
[^\[\]\n]*       : match 0+ chars other than those char class
$                : match end of string

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM