我正在尝试在Javascript中创建一个可以放置字符的有限订单的正则表达式,但是我无法使验证完全正确。
表达的标准有点复杂。用户必须使用以下条件输入字符串:
这可能听起来有点令人困惑。
例如,以下示例有效:
<C>:Cu;
<Cu>:Cv;
/_V<C>V:C;
/_VV<Cv>VV_/:Cu;
_<V>:V1;
_<V>_:V1;
_<V>/:V1;
_<V>:*;
_<m>:n;
以下是无效的:
Cu:Cv;
Cu:Cv
CuCv;
<Cu/>:Cv;
<Cu_>:Cv;
<Cu>:Cv/;
_/<Cu>:Cv;
<Cu>/_:Cv;
他们应该像这样组合在一起验证。
<Cu>:Cv;/_V<C>V:C;_<V>:V1;_<V>/:V1;_<V>:*;_<m>:n;
希望这些例子可以帮助您理解我想要匹配的内容。
我创建了以下正则表达式并在Regex101.com上进行了测试,但这是我能来的最接近的:
\\/{0,1}_{0,1}[A-Za-z0-9]{0,}<{1}[A-Za-z0-9]{1,2}>{1}[A-Za-z0-9]{0,}_{0,1}\\/{0,1}):([A-Za-z0-9]{1,2}|\\*;$
它大多是正确的,但它允许字符串应该是无效的,例如:
_/<C>:C;
如果下划线出现在第一个正斜杠之前,则应该拒绝它。否则,我的正则表达式似乎对所有其他情况都是正确的。
如果有人对如何解决这个问题有任何建议,或者知道如何更有效地匹配所有标准,那么任何帮助都会受到赞赏。
你的意思是?
/^(?:(^|\s*;\s*)(?:\/_|_)?[a-z]*<[a-z]+>[a-z]*_?\/?:(?:[a-z0-9]+|\*)(?=;))+;$/i
我们从不区分大小写的表达式/.../i
开始,以使其更具可读性。如果您只想在单词的开头允许大写,则必须将其重写为区分大小写的表达式。
^
表示字符串的开头。 $
表示字符串的结尾。
在内部表达';'
的多次重复之后,整个字符串以(?:...)+
结束,其中+
表示1个或更多个发生。 ;$
最后包括结果中的最后一个分号。仅测试不是必需的,因为预测已经完成了工作。
(^|\s*;\s*)
每个部分都在字符串的开头或分号后面包含任意空格,包括换行符。如果您不想允许空格和制表符,请使用\n
。
(?:...|...)
是一个未被捕获的替代品。字符或组之后的?
是量词0/1 - 无或一次。
所以(?:\/_|_)?
的意思是'/',''或者什么也没有。如果你想允许以单斜杠开头的字符串,请使用\/?_?
。
[a-z]*<[a-z]+>[a-z]*
后跟0个或更多字母
内部至少有一个字母,后面跟着0个或更多字母。
_?\/?:
可选'_',可选'/',强制:在此序列中。
(?:[a-z0-9]+|\*)
冒号后面的部分包含字母和数字或星号。
(?=;)
预测:每个小组必须后面跟一个分号。预测条件不会移动搜索位置。
以下似乎符合所有标准:
(?:^|;)(\/?_?[a-zA-Z0-9]*<(?:[a-zA-Z]|C[uv]?)>[a-zA-Z0-9]*_?\/?):([a-zA-Z0-9]+|\*)(?=;|$)
它将每个“组”放入捕获组中,以便您可以单独访问它们。
细节:
(?:^|;)
一个非捕获组,用于确保字符串在开头或以分号开头。(
第1组的开始。
\/?_?
可选的正斜杠,后跟可选的下划线。
[a-zA-Z0-9]*
任何字母或数字 - 匹配0或更多。
<(?:[a-zA-Z]|C[uv]?)>
强制性的<>
对包含一个字母或大写字母C
,后跟小写u
或v
。
[a-zA-Z0-9]*
任何字母或数字 - 匹配0或更多。
_?\/?
可选的下划线,后跟可选的正斜杠。)
小组结束1。:
字面上匹配冒号字符。([a-zA-Z0-9]+|\*)
第2组 - 包含一个或多个数字或字母或单个*
字符。(?=;|$)
一个积极的前瞻,以确保字符串后面跟一个分号或最后。