Como dividir uma expressão regular longa em várias linhas em JavaScript?

Tenho uma expressão regular muito longa, que desejo dividir em várias linhas no meu código JavaScript para manter cada comprimento de linha de 80 caracteres de acordo com as regras do JSLint. É apenas melhor para ler, eu acho. Aqui está um exemplo de padrão:

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,}))$/; 

Você poderia convertê-lo em uma string e criar a expressão chamando 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('')); 

Notas:

  1. ao converter a expressão literal em uma string, você precisa escaping de todas as barras invertidas quando barras invertidas são consumidas ao avaliar um literal de string . (Veja o comentário de Kayo para mais detalhes.)
  2. RegExp aceita modificadores como um segundo parâmetro

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

[ Adição ES20xx (modelo marcado)]

No ES20xx, você pode usar modelos marcados . Veja o trecho.

Nota:

  • A desvantagem aqui é que você não pode usar espaço em branco simples na string de expressão regular (use sempre \s , \s+ , \s{1,x} , \t , \n etc).
 (() => { 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); })(); 

Estendendo a resposta do @KooiInc, você pode evitar a fuga manual de todos os caracteres especiais usando a propriedade source do object RegExp .

Exemplo:

 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 ); 

ou se você quiser evitar a repetição da propriedade .source , você pode fazê-lo usando a function 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('')); 

No ES6, a function map pode ser reduzida para: .map(r => r.source)

Usando strings no new RegExp é estranho porque você deve escaping todas as barras invertidas. Você pode escrever regexes menores e concatená-los.

Vamos dividir esse regex

 /^foo(.*)\bar$/ 

Vamos usar uma function para tornar as coisas mais bonitas depois

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

E agora vamos balançar

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

Uma vez que tem um custo, tente construir o regex real apenas uma vez e depois usá-lo.

O regex acima está faltando algumas barras pretas que não estão funcionando corretamente. Então, eu editei o regex. Por favor, considere este regex que funciona 99,99% para validação de e-mail.

 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('')); 

Pessoalmente, eu iria para um regex menos complicado:

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

Claro, é menos preciso do que o seu padrão atual, mas o que você está tentando realizar? Você está tentando detectar erros acidentais nos quais seus usuários podem entrar ou teme que seus usuários possam tentar inserir endereços inválidos? Se é o primeiro, eu vou para um padrão mais fácil. Se for o último, alguma verificação respondendo a um e-mail enviado para esse endereço pode ser uma opção melhor.

No entanto, se você quiser usar seu padrão atual, seria (IMO) mais fácil de ler (e manter!) Construindo-o a partir de sub-padrões menores, como este:

 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 + ")$"); 

Para evitar a join matriz, você também pode usar a seguinte syntax:

 var pattern = 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,}))$');