3

ロケーション文字列を識別する最も効率的な方法で検証しようとしていますが、どちらにもわずかな違いがあり、メイン文字列の前後に一連の文字が含まれている可能性があります。

有効な値:

ナンバー1

14-36-085-17 W6
14-36-085-17-W6
14-36-085-17W6

2番

D 096 H 094A15

上記のいずれかの数値 3 は、メインの文字列の前に 3 桁、後に 2 桁の数字を使用できます (または使用できません)。

100 14-36-085-17W6 00
200 D 096 H 094A15 00

これらの 5 つの追加文字のルールは次のとおりです。

  • 1 番目 - 常に 1 または 2
  • 2 番目 - 常に 0
  • 3位 - 0~9
  • 4日 - 常に0
  • 5日 - 0~9

だから、それはそれぞれである[1-2]0[0-9]0[0-9]思います。また、最初の 3 桁は最後の 2 桁に依存し、その逆も同様であることに注意してください。最初の 3 桁は、最後の 2 桁が存在する場合にのみ存在でき、最後の 2 桁は、最初の 3 桁が存在する場合にのみ存在できます。

これにより、一致してはならない次の無効な文字列が得られます。

100 14-36-085-17W6
14-36-085-17W6 00

2つの主要な数字のコードは次のとおりです

function func(s) 
{
  var re = /(^\d{2}-\d{2}-\d{3}-\d{2}W\d$)|(^[A-D] [0-9]{3} [A-L] [0-9]{3}[A-P][0-9]{2}$)/;
  return re.test( s );
}

最初の検証では、ケース番号 1 の #3 を使用することのみを想定しています。これは、スペース、ダッシュ、または有効なものを使用する方法がわからないためです。

4

5 に答える 5

2

一度に大きな正規表現を構築したくはありません。読むのが難しく、維持するのが難しいでしょう。また、休暇中にカンクンでビーチでマルガリータをすすりながらデバッグをしなければならないとき、仲間の開発者はあなたを嫌うでしょう。

したがって、明確で意味のあるチャンクに分割することをお勧めします (ここで判断する必要があります。それはあなたのドメインです)。多分このようなもの。

var prefix = '([12]0[0-9] )';
var suffix = '( 0[0-9])';
// ? optionally matches the preceding item.
// And don't forget to escape backslashes when creating
// a regexp from a string.
var num1 = '\\d{2}-\\d{2}-\\d{3}-\\d{2}[- ]?W\\d';
var num2 = '[A-D] [0-9]{3} [A-L] [0-9]{3}[A-P][0-9]{2}';
var numbers = '(' + num1 + '|' + num2 + ')';
var pattern = '^(' + prefix + numbers + suffix + '|' + numbers + ')$';
// Instead of creating a large regexp literal all in
// one go, you can build up the regexp pattern from strings,
// and then use RegExp(pattern) to make a regexp instance.
var rx = RegExp(pattern);

rxこれで、入力番号と照合するために使用できます。より意味のある変数名を自由に使用してください。

しかし、そのままにしておかないでください。このコードは、いくつかのテストのために叫んでいます。

var testcases = [
    {
        name: 'Number 1',
        tests: [
            {input: '14-36-085-17 W6', expected: true},
            {input: '14-36-085-17-W6', expected: true},
            {input: '14-36-085-17W6', expected: true}
        ]
    },
    {
        name: 'Number 2',
        tests: [
            {input: 'D 096 H 094A15', expected: true}
        ]
    },
    {
        name: 'Number 3',
        tests: [
            {input: '100 14-36-085-17W6 00', expected: true},
            {input: '200 D 096 H 094A15 00', expected: true},
            {input: '100 14-36-085-17W6', expected: false},
            {input: '14-36-085-17W6 00', expected: false}
        ]
    }
];

正規表現を試してみましょう。Chrome の開発者コンソールでこれらのテストを実行しているだけです (F12そのため)。

testcases.forEach(function(testcase){
    console.log(testcase.name);
    testcase.tests.forEach(function(test){
        var result = rx.test(test.input);
        console.log(test.input + '  result: ' +
                (result ? 'match' : 'no match') +
                (result === test.expected ? ' [pass]' : ' [**FAIL**]'));
    });
    console.log('');
});

そして出力。

    ナンバー1
    14-36-085-17 W6 結果:試合【合格】
    14-36-085-17-W6 結果: 試合 [合格]
    14-36-085-17W6 結果:試合【合格】

    2番
    D 096 H 094A15 結果: 一致 [合格]

    ナンバー 3
    100 14-36-085-17W6 00 結果: 一致 [合格]
    200 D 096 H 094A15 00 結果: 一致 [合格]
    100 14-36-085-17W6 結果: 不一致 [合格]
    14-36-085-17W6 00 結果: 不一致 [合格]

偉大な。テストを行うことで、自信を持って変更を加えることができ、変更しても何も壊れていないという安心感が得られます。そして、私はあなたにばかげた答えをしていないという自信を与えてくれます. 検索すると、テストの作成を容易にする自動化された単体テスト フレームワークが多数利用できることがわかります。私があなたに与えたのは初歩的な例です。しかし、自動化されたテストをまったく実行し始めると、大きな成果が得られます。その後のすべてが洗練です。

ちなみに、これらのテストは、質問で有効または無効として提供した例にすぎません(ありがとうございます!)。いくつかの例を見つけて、これに基づいて構築することをお勧めします。うまくいけば、私が行ったことが何らかの形で十分ではないことが判明した場合に、ここからそれを取得できるように、十分な指針を提供したことを願っています.

これは、正規表現の回答としては少しやり過ぎに思えるかもしれませんが、物事を管理しやすくするためにいくつかの機械を推奨することなく、検証に巨大な正規表現を使用することを明確な良心をもって推奨することはできません。


さらに読む
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
http://en.wikipedia.org/wiki/Unit_testing

于 2013-07-08T22:21:55.070 に答える
1

@SamuelReidの回答に対するコメントの要件に基づいて、正規表現は醜くなります。2 つのストリング要件が互いにオン/オフ (ストリングの反対側) に依存している場合、これは難しくなります。

正規表現:

/^(?:(?:[12]0\d (?:\d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d|[A-D] \d{3} [A-L] \d{3}[A-P]\d{2}) 0\d)|(?:\d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d|[A-D] \d{3} [A-L] \d{3}[A-P]\d{2}))$/

適切にフォーマットされた/読みやすいバージョン:

/^
  (?:
    (?:
      [12]0\d[ ]
      (?:
        \d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d
        |
        [A-D] \d{3} [A-L] \d{3}[A-P]\d{2}
      )
      [ ]0\d
    )
    |
    (?:
      \d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d
      |
      [A-D] \d{3} [A-L] \d{3}[A-P]\d{2}
    )
  )
$/x

[](空白は重要であり、フリースペースモード(xフラグ)では失われるため、それらを強調するために空白の周りに追加されました-これはJSではサポートされていません)

「読みやすいバージョン」からわかるように、基本的な正規表現は、追加された式と式の1つで2回行われ[12]0\d[ ]ます[ ]0\d

正規表現でライブを見る


文字列の途中で一致させる必要がある場合は、正規表現の両端にある^$アンカーを交換するだけです。\b

and\bの代わりに境界を使用した正規表現^$

/\b(?:(?:[12]0\d (?:\d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d|[A-D] \d{3} [A-L] \d{3}[A-P]\d{2}) 0\d)|(?:\d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d|[A-D] \d{3} [A-L] \d{3}[A-P]\d{2}))\b/

于 2013-07-08T21:10:37.677 に答える
0

それはそれほど悪いことではありません (確かに大きな正規表現ですが)。これは、パターンの両方と、先頭または末尾の追加可能な数字をカバーする必要があります。

必要なパターンは次のとおりです。

var re = new RegExp("^([1-2]0\\d )?(\\d{2}-\\d{2}-\\d{3}-\\d{2}[\- ]?W\\d|[A-D] \\d{3} [A-L] \\d{3}[A-P]\\d{2})( 0\\d)?$");

. . . または、代わりに:

var re = /^([1-2]0\d )?(\d{2}-\d{2}-\d{3}-\d{2}[\- ]?W\d|[A-D] \d{3} [A-L] \d{3}[A-P]\d{2})( 0\d)?$/

コードの残りの部分は、それで正常に動作するはずです。

編集:「オールオアナッシング」の新しい理解に基づいて、アプローチを更新しました。. . 一般的なパターンから構築された 2 つの正規表現パターンに基づいて、2 つのテストを行います。

var sCorePattern = "(\\d{2}-\\d{2}-\\d{3}-\\d{2}[\- ]?W\\d|[A-D] \\d{3} [A-L] \\d{3}[A-P]\\d{2})";
var sSecondaryPattern = "[1-2]0\\d " + sCorePattern + " 0\\d";

var regCorePattern = new RegExp("^" + sCorePattern + "$");
var regSecondaryPattern = new RegExp("^" + sSecondaryPattern + "$");

if (regCorePattern.test(s) || regSecondaryPattern.test(s)) {
    . . . do stuff . . .
}
else {
    . . . do other stuff . . .
}

私にとっては、読みやすさを犠牲にすることなく、効率と再利用をうまく組み合わせたものです。:)

于 2013-07-08T22:11:39.477 に答える