Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
85 views
in Technique[技术] by (71.8m points)

javascript - Restricting Character length in Regular expression

I am using the following regular expression without restricting any character length

var test =  /^(a-z|A-Z|0-9)*[^$%^&*;:,<>?()""']*$/ //Works Fine

In above when I am trying to restrict the characters length to 15 as below, it throws an error.

var test =  /^(a-z|A-Z|0-9)*[^$%^&*;:,<>?()""']*${1,15}/    //**Uncaught SyntaxError: Invalid regular expression**

Please help me to make the above regEx work with the characters limit to 15.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You cannot apply quantifiers to anchors. Instead, to restrict the length of the input string, use a lookahead anchored at the beginning:

// ECMAScript (JavaScript, C++)
^(?=.{1,15}$)[a-zA-Z0-9]*[^$%^&*;:,<>?()"']*$
^^^^^^^^^^^

// Or, in flavors other than ECMAScript and Python
A(?=.{1,15}z)[a-zA-Z0-9]*[^$%^&*;:,<>?()"']*z
^^^^^^^^^^^^^^^

// Or, in Python
A(?=.{1,15})[a-zA-Z0-9]*[^$%^&*;:,<>?()"']*
^^^^^^^^^^^^^^^

Also, I assume you wanted to match 0 or more letters or digits with (a-z|A-Z|0-9)*. It should look like [a-zA-Z0-9]* (i.e. use a character class here).

Why not use a limiting quantifier, like {1,15}, at the end?

Quantifiers are only applied to the subpattern to the left, be it a group or a character class, or a literal symbol. Thus, ^[a-zA-Z0-9]*[^$%^&*;:,<>?()"']{1,15}$ will effectively restrict the length of the second character class [^$%^&*;:,<>?()"'] to 1 to 15 characters. The ^(?:[a-zA-Z0-9]*[^$%^&*;:,<>?()"']*){1,15}$ will "restrict" the sequence of 2 subpatterns of unlimited length (as the * (and +, too) can match unlimited number of characters) to 1 to 15 times, and we still do not restrict the length of the whole input string.

How does the lookahead restriction work?

The (?=.{1,15}$) / (?=.{1,15}z) / (?=.{1,15}) positive lookahead appears right after ^/A (note in Ruby, A is the only anchor that matches only start of the whole string) start-of-string anchor. It is a zero-width assertion that only returns true or false after checking if its subpattern matches the subsequent characters. So, this lookahead tries to match any 1 to 15 (due to the limiting quantifier {1,15}) characters but a newline right at the end of the string (due to the $/z/ anchor). If we remove the $ / z / anchor from the lookahead, the lookahead will only require the string to contain 1 to 15 characters, but the total string length can be any.

If the input string can contain a newline sequence, you should use [sS] portable any-character regex construct (it will work in JS and other common regex flavors):

// ECMAScript (JavaScript, C++)
^(?=[sS]{1,15}$)[a-zA-Z0-9]*[^$%^&*;:,<>?()"']*$
 ^^^^^^^^^^^^^^^^^

// Or, in flavors other than ECMAScript and Python
A(?=[sS]{1,15}z)[a-zA-Z0-9]*[^$%^&*;:,<>?()"']*z
  ^^^^^^^^^^^^^^^^^^

// Or, in Python
A(?=[sS]{1,15})[a-zA-Z0-9]*[^$%^&*;:,<>?()"']*
  ^^^^^^^^^^^^^^^^^^

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...