2014-11-04 64 views
1

正则表达式先行问题需要支持下列格式用贪婪的量词

3位数字可选空间后跟以下字符集ACERV内指定了三个非重复的字符(空格只在两个字符之间是有效的)

有效格式:

123 
123 A 
123 A v 
123 CER 

无效格式:

123A 
123 AA 
123 A - when followed by a space 

我到目前为止 - 我可能是在与不一定需要向前看符号复杂的:

^([0-9]{3})           # - first 3 digits 
(\s(?=[ACERV]))([ACERV])       # - allow space only when followed by ACERV 
(?!\3)(?=[ACERV ]{0,1})([ACERV ]{0,1})    # - do not allow 1st char to repeat 
(?!\3)            # - do not allow 1st char to repeat 
(?!\4)            # - do not allow 2nd to repeat 
(?!\s)            # - do not allow trailing space 
(?=[ACERV]{0,1})([ACERV]{0,1})|[0-9]{3}$ 

当先行加入它不匹配的有效格式123(\ 4?!) A - 将(?!\ 4)上的量词修改为(?!\ 4)*或(?!\ 4)?允许123 A匹配,但允许重复第一个或第二个字符。

+0

为什么123A无效? – nu11p01n73R 2014-11-04 21:13:10

+0

不重复相邻或任何地方? – sln 2014-11-04 21:17:27

+0

非重复仅在文本字段的格式(即,仅123 AEV的一个单一的入口将被允许) – 2014-11-04 22:26:22

回答

1

不完全确定的要求,这适用于您的示例。

# ^(?i)\d{3}(?:[ ](?:([ACERV])[ ]?(?![ACERV ]*\1)){1,3}(?<![ ]))?$ 

^      # BOL 
(?i)     # Case insensitive modifier 
\d{3}     # 3 digits 
(?:     # Cluster grp, character block (optional) 
     [ ]     # Space, required 
     (?:     # Cluster grp 
      ([ACERV])   # (1), Capture single character [ACERV] 
      [ ]?     # [ ], optional 
      (?!     # Negative lookahead 
       [ACERV ]*    # As many [ACERV] or [ ] needed 
       \1      # to find what is captured in group 1 
             # Found it, the assertion fails 
      )      # End Negative lookahead 
    ){1,3}     # End Cluster grp, gets 1-3 [ACERV] characters 
     (?<! [ ])    # No dangling [ ] at end 
)?      # End Cluster grp, character block (optional) 
$      # EOL 

更新 -调整更换回顾后。

# ^(?i)\d{3}(?!.*[ ]$)(?:[ ](?:([ACERV])[ ]?(?![ACERV ]*\1)){1,3})?$ 

^      # BOL 
(?i)     # Case insensitive modifier 
\d{3}     # 3 digits 
(?! .* [ ] $)   # No dangling [ ] at end 
(?:     # Cluster grp, character block (optional) 
     [ ]     # Space, required 
     (?:     # Cluster grp 
      ([ACERV])   # (1), Capture single character [ACERV] 
      [ ]?     # [ ], optional 
      (?!     # Negative lookahead 
       [ACERV ]*    # As many [ACERV] or [ ] needed 
       \1      # to find what is captured in group 1 
             # Found it, the assertion fails 
      )      # End Negative lookahead 
    ){1,3}     # End Cluster grp, gets 1-3 [ACERV] characters 
)?      # End Cluster grp, character block (optional) 
$      # EOL 
+0

这看起来很有希望标记为已回答 – 2014-11-04 22:31:51

+0

任何机会,你可以发表评论下一节之前尝试所有的变化:((:[ACERV](<[] {2})) * \ 1)){1,3}(?<![]))? – 2014-11-05 12:41:23

+0

@DavidBrown - 删除了不需要的断言,添加了评论。 – sln 2014-11-05 13:38:15

0

如何对正则表达式

^\d{3}(?:$|\s)(?:([ACERV])(?!\1)|\s(?!$|\1))*$ 

将匹配字符串

123 
123 A 
123 A V 
123 CER 

见正则表达式在http://regex101.com/r/mW5qZ9/9

  • ^锚正则表达式如何符合项目在字符串的开头

  • \d{3}比赛3 occurence任何数字的

  • (?:$|\s)匹配串$或空间的端部,\s

  • (?:\s?([ACERV])(?!\1)){0,3}匹配非重复字符从

    • (?:)非捕获组

    • \s?可选空间

    • ([ACERV])中的字符匹配的类

    • (?:([ACERV])(?!\1)|\s(?!$|\1))断言,正则表达式后面没有\1,最近被捕获的。确保字符不重复。

      • (?!\1)断言,字符类不能被接着重复字符

      • \s(?!$|\1))断言,如果它是一个空间,那么它不能被随后柱的端部或重复字符从\1

    • {0,3}量词指定最小出现次数为零和最大发生次数为3

  • $将正则表达式锚定在字符串末尾。

+0

匹配'123 V V' – sln 2014-11-04 21:53:46

+0

不知道你的你的定义#matched的意思......我可能没有在最初的问题规定得很好。紧随可选字符后需要数字后的空格。所以123A不应该匹配。 – 2014-11-04 22:21:39

+0

@DavidBrown在答案中纠正。希望它匹配精细现在 – nu11p01n73R 2014-11-05 04:18:12

0

一个计划是一个简单的正则表达式来拉开字符串,那么第二步骤,以验证字符不重复。

// check all characters in a string are unique, 
// by ensuring that each character is its own first appearance 
function unique_characters(str) { 
    return str.split('').every(function(chr, i, chrs) { 
     return chrs.indexOf(chr) === i; 
    }); 
} 

// check that the code is valid 
function valid_code(str) { 
    var spacepos = str.indexOf(' '); 
    return unique_characters(str) && 
     (spacepos === -1 || (spacepos === 1 && str.length === 3)); 
} 

// check basic format and pull out code portion 
function check_string(str) { 
    var matches = str.match(/^\d{3} ?([ACERV ]{0,3})$/i); 
    valid = matches && valid_code(matches[1]); 
    return valid; 
} 

>> inputs = ['123', '123 A', '123 A v', '123 CER', '123A', '123 AA', '123 A '] 
[true, true, true, true, true, false, false] 

第四个测试案例表明是有效的,因为如果空间确实是可选的,那么如果123 A是有效的,那么它似乎123A将是有效的为好。

这种方法的一个可能的好处是,如果引入额外的验证规则,他们可以更容易地比一个巨大的正则表达式内碴左右实现。