在正则表达式中强制使用严格的字符顺序

时间:2018-09-18 02:37:29

标签: javascript regex

我正在尝试用Javascript创建一个正则表达式,以限制可放置字符的顺序,但是我无法使验证完全正确。

表达式的标准有点复杂。用户必须输入符合以下条件的字符串:

  1. 字符串包含两个部分,一个初始组和一个结束组。
  2. 各组之间用冒号(:)隔开。
  3. 字符串之间用分号(;)分隔。
  4. 初始组可以以一个可选的正斜杠开始,并以一个可选的正斜杠结束,但是这些正斜杠可能不会出现在组中的其他任何地方。
  5. 在正斜杠内,一个可选的下划线可能出现在两端,但可能不会出现在组中的其他任何地方。
  6. 在这些可选元素内,用户可以输入任意数量的数字或字母(大写或小写),但是这些字符之一必须用尖括号(<>)包围。
  7. 如果括号内的字母为大写C,则其后可能是小写u或v之一。
  8. 端基可以包含一个或多个数字或字母,大写或小写(如果是大写C,则可以跟小写u或v。)或一个星号(*),但不能同时包含两者。
  9. 字符串必须能够通过多个分组进行验证。

这听起来有些混乱。

例如,以下示例有效:

<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;

如果下划线出现在第一个正斜杠之前,则应将其拒绝。否则,我的正则表达式对于所有其他情况似乎都是正确的。

如果任何人对如何解决此问题有任何建议,或者知道一种更有效地匹配所有条件的方法,我们将不胜感激。

2 个答案:

答案 0 :(得分:2)

以下内容似乎符合所有条件:

Dim testDate As DateTime = DateTime.MinValue

testDate = DateTime.Now.ToString("yyyy'/'MM'/'dd")

Regex101 demo

它将每个“组”置于一个捕获组中,以便您可以分别访问它们。

详细信息:

  • (?:^|;)(\/?_?[a-zA-Z0-9]*<(?:[a-zA-Z]|C[uv]?)>[a-zA-Z0-9]*_?\/?):([a-zA-Z0-9]+|\*)(?=;|$) 一个非捕获组,可确保字符串以开头或以分号开头。

  • (?:^|;)第1组的开始。

    • (可选的正斜杠,后跟可选的下划线。

    • \/?_?任何字母或数字-匹配零个或多个。

    • [a-zA-Z0-9]*强制性<(?:[a-zA-Z]|C[uv]?)>对,其中包含一个字母或大写字母<>,后跟小写字母Cu

    • v任何字母或数字-匹配零个或多个。

    • [a-zA-Z0-9]*可选的下划线,后跟可选的正斜杠。

  • _?\/?组1的结尾。

  • )从字面上匹配冒号。

  • :第2组-包含一个或多个数字或字母或单个([a-zA-Z0-9]+|\*)字符。

  • *为肯定的Lookahead,以确保字符串后跟分号或末尾。

答案 1 :(得分:1)

你是这个意思吗?

/^(?:(^|\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]+|\*)冒号后面的部分包含字母和数字或星号。

(?=;)前瞻:每个组后面必须加一个分号。先行条件不会移动搜索位置。