167

非常に長い正規表現があり、JSLint 規則に従って各行の長さを 80 文字に保つために、JavaScript コードで複数の行に分割したいと考えています。読書にはちょうどいいと思います。パターンのサンプルは次のとおりです。

var pattern = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
4

11 に答える 11

144

@KooiInc の回答を拡張するsourceと、オブジェクトのプロパティを使用して、すべての特殊文字を手動でエスケープすることを回避できRegExpます。

例:

var urlRegex= new RegExp(''
  + /(?:(?:(https?|ftp):)?\/\/)/.source     // protocol
  + /(?:([^:\n\r]+):([^@\n\r]+)@)?/.source  // user:pass
  + /(?:(?:www\.)?([^\/\n\r]+))/.source     // domain
  + /(\/[^?\n\r]+)?/.source                 // request
  + /(\?[^#\n\r]*)?/.source                 // query
  + /(#?[^\n\r]*)?/.source                  // anchor
);

.sourceまたは、プロパティの繰り返しを避けたい場合は、次のArray.map()関数を使用して実行できます。

var urlRegex= new RegExp([
  /(?:(?:(https?|ftp):)?\/\/)/      // protocol
  ,/(?:([^:\n\r]+):([^@\n\r]+)@)?/  // user:pass
  ,/(?:(?:www\.)?([^\/\n\r]+))/     // domain
  ,/(\/[^?\n\r]+)?/                 // request
  ,/(\?[^#\n\r]*)?/                 // query
  ,/(#?[^\n\r]*)?/                  // anchor
].map(function(r) {return r.source}).join(''));

ES6 では、map 関数は次のように縮小できます。 .map(r => r.source)

于 2016-01-12T22:34:09.153 に答える
137

それを文字列に変換し、次のように呼び出して式を作成できますnew RegExp()

var myRE = new RegExp (['^(([^<>()[\]\\.,;:\\s@\"]+(\\.[^<>(),[\]\\.,;:\\s@\"]+)*)',
                        '|(\\".+\\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.',
                        '[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\\.)+',
                        '[a-zA-Z]{2,}))$'].join(''));

ノート:

  1. 式リテラルを文字列に変換するときは、文字列リテラルを評価するときにバックスラッシュが消費されるため、すべてのバックスラッシュをエスケープする必要があります。(詳しくは佳代さんのコメントをご覧ください。)
  2. RegExp修飾子を 2 番目のパラメーターとして受け入れます

    /regex/g=>new RegExp('regex', 'g')

ES20xx (タグ付きテンプレート)の追加】

ES20xx では、タグ付きテンプレートを使用できます。スニペットを参照してください。

ノート:

  • ここでの欠点は、正規表現文字列でプレーンな空白を使用できないことです (常に , , , などを使用\s\s+\s{1,x}ください\t) \n

(() => {
  const createRegExp = (str, opts) => 
    new RegExp(str.raw[0].replace(/\s/gm, ""), opts || "");
  const yourRE = createRegExp`
    ^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|
    (\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|
    (([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$`;
  console.log(yourRE);
  const anotherLongRE = createRegExp`
    (\byyyy\b)|(\bm\b)|(\bd\b)|(\bh\b)|(\bmi\b)|(\bs\b)|(\bms\b)|
    (\bwd\b)|(\bmm\b)|(\bdd\b)|(\bhh\b)|(\bMI\b)|(\bS\b)|(\bMS\b)|
    (\bM\b)|(\bMM\b)|(\bdow\b)|(\bDOW\b)
    ${"gi"}`;
  console.log(anotherLongRE);
})();

于 2012-09-07T11:20:23.527 に答える
30

new RegExpすべてのバックスラッシュをエスケープする必要があるため、文字列を使用するのは厄介です。より小さな正規表現を記述して連結することができます。

この正規表現を分割しましょう

/^foo(.*)\bar$/

関数を使用して、後で物事をより美しくします

function multilineRegExp(regs, options) {
    return new RegExp(regs.map(
        function(reg){ return reg.source; }
    ).join(''), options);
}

そして今、レッツ・ロック

var r = multilineRegExp([
     /^foo/,  // we can add comments too
     /(.*)/,
     /\bar$/
]);

コストがかかるため、実際の正規表現を一度だけ作成してから使用してください。

于 2015-06-14T23:37:57.320 に答える
6

上記の正規表現には、正しく機能していない黒いスラッシュがいくつかありません。それで、正規表現を編集しました。電子メールの検証で 99.99% 機能するこの正規表現を検討してください。

let EMAIL_REGEXP = 
new RegExp (['^(([^<>()[\\]\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\.,;:\\s@\"]+)*)',
                    '|(".+"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.',
                    '[0-9]{1,3}\])|(([a-zA-Z\\-0-9]+\\.)+',
                    '[a-zA-Z]{2,}))$'].join(''));
于 2016-12-27T16:18:57.030 に答える
0

個人的には、より単純な正規表現を使用します。

/\S+@\S+\.\S+/

確かに、現在のパターンよりも正確ではありませんが、何を達成しようとしているのでしょうか? ユーザーが入力する可能性のある偶発的なエラーを検出しようとしていますか? または、ユーザーが無効なアドレスを入力しようとするのではないかと心配していますか? それが最初なら、もっと簡単なパターンを選びます。後者の場合は、そのアドレスに送信された電子メールに返信することによる確認がより適切なオプションになる可能性があります。

ただし、現在のパターンを使用したい場合は、次のように、より小さなサブパターンから構築することで、(IMO) 読みやすく (そして保守も!) 容易になります。

var box1 = "([^<>()[\]\\\\.,;:\s@\"]+(\\.[^<>()[\\]\\\\.,;:\s@\"]+)*)";
var box2 = "(\".+\")";

var host1 = "(\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])";
var host2 = "(([a-zA-Z\-0-9]+\\.)+[a-zA-Z]{2,})";

var regex = new RegExp("^(" + box1 + "|" + box2 + ")@(" + host1 + "|" + host2 + ")$");
于 2012-09-07T11:39:40.747 に答える