web-dev-qa-db-ja.com

JavaScriptで長い正規表現を複数の行に分割する方法は?

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

var pattern = /^(([^<>()[\]\\.,;:\[email protected]\"]+(\.[^<>()[\]\\.,;:\[email protected]\"]+)*)|(\".+\"))@((\[[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,}))$/;
123
Nik Sumeiko

new RegExp()を呼び出して、文字列に変換し、式を作成できます。

_var myRE = new RegExp (['^(([^<>()[\]\\.,;:\\[email protected]\"]+(\\.[^<>(),[\]\\.,;:\\[email protected]\"]+)*)',
                        '|(\\".+\\"))@((\\[[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. expression literalを文字列に変換する場合、string literalを評価するときにバックスラッシュが消費されるため、すべてのバックスラッシュをエスケープする必要があります。 (詳細については、嘉代のコメントを参照してください。)
  2. RegExpは、2番目のパラメーターとして修飾子を受け入れます

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

[Addition 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`
    ^(([^<>()[\]\\.,;:\[email protected]\"]+(\.[^<>()[\]\\.,;:\[email protected]\"]+)*)|
    (\".+\"))@((\[[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);
})();_
104
KooiInc

@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(r => r.source)

98
korun

すべてのバックスラッシュをエスケープする必要があるため、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$/
]);

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

23
Riccardo Galli

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

let EMAIL_REGEXP = 
new RegExp (['^(([^<>()[\\]\\\.,;:\\[email protected]\"]+(\\.[^<>()\\[\\]\\\.,;:\\[email protected]\"]+)*)',
                    '|(".+"))@((\\[[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(''));
4
Anvesh Reddy

ここには良い答えがありますが、完全を期すために、Javascriptの継承のコア機能を プロトタイプチェーン で言及する必要があります。次のようなものがアイデアを示しています。

RegExp.prototype.append = function(re) {
  return new RegExp(this.source + re.source, this.flags);
};

let regex = /[a-z]/g
.append(/[A-Z]/)
.append(/[0-9]/);

console.log(regex); //=> /[a-z][A-Z][0-9]/g
2
James Donohue

配列joinを回避するには、次の構文も使用できます。

var pattern = new RegExp('^(([^<>()[\]\\.,;:\[email protected]\"]+' +
  '(\.[^<>()[\]\\.,;:\[email protected]\"]+)*)|(\".+\"))@' +
  '((\[[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,}))$');
1
andreasonny83

単純に文字列操作を使用できます。

var pattenString = "^(([^<>()[\]\\.,;:\[email protected]\"]+(\.[^<>()[\]\\.,;:\[email protected]\"]+)*)|"+
"(\".+\"))@((\[[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,}))$";
var patten = new RegExp(pattenString);
0
Mubeena

個人的には、それほど複雑ではない正規表現を使用します。

/\[email protected]\S+\.\S+/

もちろん、現在のパターンよりも少ない正確なですが、何を達成しようとしていますか?ユーザーが入力する可能性がある偶発的なエラーをキャッチしようとしていますか、またはユーザーが無効なアドレスを入力しようとするのではないかと心配していますか?最初の場合は、より簡単なパターンを探します。後者の場合は、そのアドレスに送信された電子メールに応答することで検証する方が適切なオプションです。

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

var box1 = "([^<>()[\]\\\\.,;:\[email protected]\"]+(\\.[^<>()[\\]\\\\.,;:\[email protected]\"]+)*)";
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 + ")$");
0
Bart Kiers