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

问题描述 投票:1回答:2

我正在尝试在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;

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

如果有人对如何解决这个问题有任何建议,或者知道如何更有效地匹配所有标准,那么任何帮助都会受到赞赏。

javascript regex
2个回答
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]+|\*)冒号后面的部分包含字母和数字或星号。

(?=;)预测:每个小组必须后面跟一个分号。预测条件不会移动搜索位置。


2
投票

以下似乎符合所有标准:

(?:^|;)(\/?_?[a-zA-Z0-9]*<(?:[a-zA-Z]|C[uv]?)>[a-zA-Z0-9]*_?\/?):([a-zA-Z0-9]+|\*)(?=;|$)

Regex101 demo

它将每个“组”放入捕获组中,以便您可以单独访问它们。

细节:

  • (?:^|;)一个非捕获组,用于确保字符串在开头或以分号开头。
  • (第1组的开始。 \/?_?可选的正斜杠,后跟可选的下划线。 [a-zA-Z0-9]*任何字母或数字 - 匹配0或更多。 <(?:[a-zA-Z]|C[uv]?)>强制性的<>对包含一个字母或大写字母C,后跟小写uv[a-zA-Z0-9]*任何字母或数字 - 匹配0或更多。 _?\/?可选的下划线,后跟可选的正斜杠。
  • )小组结束1。
  • :字面上匹配冒号字符。
  • ([a-zA-Z0-9]+|\*)第2组 - 包含一个或多个数字或字母或单个*字符。
  • (?=;|$)一个积极的前瞻,以确保字符串后面跟一个分号或最后。
© www.soinside.com 2019 - 2024. All rights reserved.