2

以下のフォーマットをサポートする必要があります

3 桁の数字の後にオプションのスペースが続き、その後に次の文字セット ACERV 内で指定された 3 つの非反復文字が続きます (スペースは 2 つの文字の間でのみ有効です)。

有効な形式:

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}$

先読み (?!\4) が追加されると、有効な形式との一致に失敗します 123 A - (?!\4) の数量詞を (?!\4)* または (?!\4)? に変更します。123 A を一致させることができますが、1 番目または 2 番目の文字を繰り返すことができます。

4

3 に答える 3

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
于 2014-11-04T21:42:10.307 に答える
0

1 つの計画は、文字列を分解するための単純な正規表現であり、次に文字が繰り返されていないことを検証するための 2 番目のステップです。

// 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]

4 番目のテスト ケースは有効であると表示されます。これは、スペースが実際にオプションである場合、有効である場合123 Aは有効であると思わ123Aれるからです。

この種のアプローチの考えられる利点は、追加の検証ルールが導入された場合、巨大な正規表現をいじるよりも簡単に実装できることです。

于 2014-11-05T05:05:10.333 に答える
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 回の出現に一致します

  • (?:$|\s)$文字列またはスペースの末尾に一致します。\s

  • (?:\s?([ACERV])(?!\1)){0,3}の非繰り返し文字に一致[ACERV]

    • (?: )非捕獲グループ

    • \s?オプションのスペース

    • ([ACERV])クラスの文字に一致

    • (?:([ACERV])(?!\1)|\s(?!$|\1))は、正規表現の後\1に最近キャプチャされた文字が続かないことを表明します。文字が繰り返されないようにします。

      • (?!\1)文字クラスの後に繰り返し文字を続けることはできないと断言します

      • \s(?!$|\1))スペースである場合、その後に文字列の末尾または繰り返し文字を続けることはできないと主張します\1

    • {0,3}最小出現数をゼロ、最大出現数を 3 に指定する量指定子

  • $文字列の末尾に正規表現を固定します。

于 2014-11-04T21:30:43.500 に答える