如何在JavaScript中将一个长正则表达式分割成多行?

时间:2022-07-07 21:30:12

I have a very long regular expression, which I wish to split into multiple lines in my JavaScript code to keep each line length 80 characters according to JSLint rules. It's just better for reading, I think. Here's pattern sample:

我有一个很长的正则表达式,我希望在JavaScript代码中把它分成多行,以便根据JSLint规则保持每行长度为80个字符。我想这对阅读更好。这是模式示例:

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

6 个解决方案

#1


85  

You could convert it to a string and create the expression by calling new RegExp():

可以将其转换为字符串,并通过调用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(''));

Note:

注意:

  1. when converting the expression literal to a string you need to escape all backslashes as backslashes are consumed when evaluating a string literal. (See Kayo's comment for more detail.)
  2. 当将表达式文字转换为字符串时,您需要转义所有的反斜杠,因为在计算字符串文字时,反斜杠将被使用。(详见Kayo的评论)。
  3. RegExp accepts modifiers as a second parameter

    RegExp接受修饰符作为第二个参数

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

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

#2


68  

Extending @KooiInc answer, you can avoid manually escaping every special character by using the source property of the RegExp object.

扩展@KooiInc答案,您可以通过使用RegExp对象的源属性来避免手工转义每个特殊字符。

Example:

例子:

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

or if you want to avoid repeating the .source property you can do it using the Array.map() function:

或者如果您想避免重复.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(''));

In ES6 the map function can be reduced to: .map(r => r.source)

在ES6中,map函数可以简化为:.map(r => r.source)

#3


19  

Using strings in new RegExp is awkward because you must escape all the backslashes. You may write smaller regexes and concatenate them.

在新的RegExp中使用字符串很尴尬,因为您必须避免所有的反斜杠。您可以编写更小的regexe并将它们连接起来。

Let's split this regex

让我们分裂这个正则表达式

/^foo(.*)\bar$/

We will use a function to make things more beautiful later

我们稍后将使用一个函数来使事情变得更漂亮

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

And now let's rock

现在让我们摇滚

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

Since it has a cost, try to build the real regex just once and then use that.

因为它有成本,试着只构建一次真正的正则表达式,然后使用它。

#4


4  

The regex above is missing some black slashes which isn't working properly. So, I edited the regex. Please consider this regex which works 99.99% for email validation.

上面的regex缺少一些不能正常工作的黑色斜线。所以,我编辑了regex。请考虑这个regex,它可以为电子邮件验证工作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(''));

#5


2  

Personally, I'd go for a less complicated regex:

就我个人而言,我想要一个不那么复杂的regex:

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

Sure, it is less accurate than your current pattern, but what are you trying to accomplish? Are you trying to catch accidental errors your users might enter, or are you worried that your users might try to enter invalid addresses? If it's the first, I'd go for an easier pattern. If it's the latter, some verification by responding to an e-mail sent to that address might be a better option.

当然,它不如你现在的模式准确,但是你想要完成什么?您是试图捕获用户可能输入的意外错误,还是担心您的用户可能尝试输入无效地址?如果是第一个,我会选择更简单的模式。如果是后者,通过回复发送到该地址的电子邮件进行验证可能是更好的选择。

However, if you want to use your current pattern, it would be (IMO) easier to read (and maintain!) by building it from smaller sub-patterns, like this:

但是,如果您想使用您的当前模式,通过从较小的子模式构建它(在我看来)将更容易阅读(并维护!)

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

#6


0  

To avoid the Array join, you can also use the following 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,}))$');

#1


85  

You could convert it to a string and create the expression by calling new RegExp():

可以将其转换为字符串,并通过调用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(''));

Note:

注意:

  1. when converting the expression literal to a string you need to escape all backslashes as backslashes are consumed when evaluating a string literal. (See Kayo's comment for more detail.)
  2. 当将表达式文字转换为字符串时,您需要转义所有的反斜杠,因为在计算字符串文字时,反斜杠将被使用。(详见Kayo的评论)。
  3. RegExp accepts modifiers as a second parameter

    RegExp接受修饰符作为第二个参数

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

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

#2


68  

Extending @KooiInc answer, you can avoid manually escaping every special character by using the source property of the RegExp object.

扩展@KooiInc答案,您可以通过使用RegExp对象的源属性来避免手工转义每个特殊字符。

Example:

例子:

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

or if you want to avoid repeating the .source property you can do it using the Array.map() function:

或者如果您想避免重复.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(''));

In ES6 the map function can be reduced to: .map(r => r.source)

在ES6中,map函数可以简化为:.map(r => r.source)

#3


19  

Using strings in new RegExp is awkward because you must escape all the backslashes. You may write smaller regexes and concatenate them.

在新的RegExp中使用字符串很尴尬,因为您必须避免所有的反斜杠。您可以编写更小的regexe并将它们连接起来。

Let's split this regex

让我们分裂这个正则表达式

/^foo(.*)\bar$/

We will use a function to make things more beautiful later

我们稍后将使用一个函数来使事情变得更漂亮

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

And now let's rock

现在让我们摇滚

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

Since it has a cost, try to build the real regex just once and then use that.

因为它有成本,试着只构建一次真正的正则表达式,然后使用它。

#4


4  

The regex above is missing some black slashes which isn't working properly. So, I edited the regex. Please consider this regex which works 99.99% for email validation.

上面的regex缺少一些不能正常工作的黑色斜线。所以,我编辑了regex。请考虑这个regex,它可以为电子邮件验证工作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(''));

#5


2  

Personally, I'd go for a less complicated regex:

就我个人而言,我想要一个不那么复杂的regex:

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

Sure, it is less accurate than your current pattern, but what are you trying to accomplish? Are you trying to catch accidental errors your users might enter, or are you worried that your users might try to enter invalid addresses? If it's the first, I'd go for an easier pattern. If it's the latter, some verification by responding to an e-mail sent to that address might be a better option.

当然,它不如你现在的模式准确,但是你想要完成什么?您是试图捕获用户可能输入的意外错误,还是担心您的用户可能尝试输入无效地址?如果是第一个,我会选择更简单的模式。如果是后者,通过回复发送到该地址的电子邮件进行验证可能是更好的选择。

However, if you want to use your current pattern, it would be (IMO) easier to read (and maintain!) by building it from smaller sub-patterns, like this:

但是,如果您想使用您的当前模式,通过从较小的子模式构建它(在我看来)将更容易阅读(并维护!)

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

#6


0  

To avoid the Array join, you can also use the following 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,}))$');