Javascript中是否存在RegExp.escape函数?

2020/09/26 23:01 · javascript ·  · 0评论

我只想从任何可能的字符串中创建一个正则表达式。

var usersString = "Hello?!*`~World()[]";
var expression = new RegExp(RegExp.escape(usersString))
var matches = "Hello".match(expression);

有内置的方法吗?如果没有,人们会使用什么?红宝石有RegExp.escape我觉得我不需要自己写东西,那里肯定有一些标准。谢谢!

上面链接的功能不足。它无法转义^$(字符串的开头和结尾)或-,这在字符组中用于范围。

使用此功能:

function escapeRegex(string) {
    return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}

乍看之下似乎没有必要,但转义-(以及^)使该函数适合于转义要插入字符类和正则表达式主体的字符。

转义/使该函数适合转义要在JS regex文字中使用的字符,以供以后评估。

由于逃避任何一个都没有不利之处,因此有理由逃避以涵盖更广泛的用例。

是的,如果它不是标准JavaScript的一部分,这是令人失望的。

对于使用lodash的任何人,从v3.0.0版本开始,内置_.escapeRegExp函数:

_.escapeRegExp('[lodash](https://lodash.com/)');
// → '\[lodash\]\(https:\/\/lodash\.com\/\)'

而且,如果您不想使用完整的lodash库,则可能需要该函数

这里的大多数表达式解决单个特定的用例。

没关系,但我更喜欢“始终有效”的方法。

function regExpEscape(literal_string) {
    return literal_string.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&');
}

对于正则表达式中的以下任何一种用法,这将“完全转义”文字字符串:

  • 插入正则表达式。例如new RegExp(regExpEscape(str))
  • 插入字符类。例如new RegExp('[' + regExpEscape(str) + ']')
  • 插入整数计数说明符。例如new RegExp('x{1,' + regExpEscape(str) + '}')
  • 在非JavaScript正则表达式引擎中执行。

涵盖的特殊字符:

  • -:在字符类中创建字符范围。
  • [/ ]:开始/结束字符类。
  • {/ }:开始/结束一个数字说明符。
  • (/ ):开始/结束组。
  • */ +/ ?:指定重复类型。
  • .:匹配任何字符。
  • \:转义字符,然后启动实体。
  • ^:指定匹配区域的开始,并否定字符类中的匹配。
  • $:指定匹配区域的结尾。
  • |:指定交替。
  • #:以自由间距模式指定注释。
  • \s:在自由间距模式下被忽略。
  • ,:分隔数值说明符中的值。
  • /:开始或结束表达式。
  • ::完成特殊的组类型和Perl样式的字符类的一部分。
  • !:否定零宽度组。
  • </ =:零宽度组规格的一部分。

笔记:

  • /在任何形式的正则表达式中并不是严格必需的。但是,它可以防止有人(颤抖)这样做eval("/" + pattern + "/");
  • , 确保如果字符串在数字说明符中应为整数,则它将适当地导致RegExp编译错误,而不是无提示地编译错误。
  • #\s不需要在JavaScript中进行转义,而是在许多其他方式中进行转义。如果正则表达式以后将传递给另一个程序,它们将在此处转义。

如果您还需要将来对正则表达式进行校对,以防可能增加JavaScript regex引擎功能,则建议使用更多偏执狂:

function regExpEscapeFuture(literal_string) {
    return literal_string.replace(/[^A-Za-z0-9_]/g, '\\$&');
}

该函数会转义每个字符,除非明确保证将来的正则表达式中不会使用这些字符。


对于真正喜欢卫生的人,请考虑以下情况:

var s = '';
new RegExp('(choice1|choice2|' + regExpEscape(s) + ')');

可以在JavaScript中很好地编译,但不能以其他某种方式编译。如果打算传递给其他口味,s === ''则应独立检查的null情况,如下所示:

var s = '';
new RegExp('(choice1|choice2' + (s ? '|' + regExpEscape(s) : '') + ')');

Mozilla开发人员网络的正则表达式指南提供了以下转义功能:

function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

在jQueryUI的自动完成小部件(1.9.1版)中,它们使用略有不同的正则表达式(第6753行),这是将正则表达式与@bobince方法结合使用。

RegExp.escape = function( value ) {
     return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
}

有一个ES7提案RegExp.escape在https://github.com/benjamingr/RexExp.escape/,与可用填充工具https://github.com/ljharb/regexp.escape

没有什么可以阻止您仅转义每个非字母数字字符的:

usersString.replace(/(?=\W)/g, '\\');

在执行操作时,您会失去一定程度的可读性,re.toString()但会获得很多简化(和安全性)。

根据ECMA-262,在一方面,正则表达式“的语法的字符”总是非字母数字,使得结果是安全的,和特殊的转义序列(\d\w\n)总是字母数字,使得没有假控制逃逸会产生。

这是一个较短的版本。

RegExp.escape = function(s) {
    return s.replace(/[$-\/?[-^{|}]/g, '\\$&');
}

这包括非元字符%&',和,,但JavaScript的正则表达式规范允许这样做。

XRegExp具有转义功能:

XRegExp.escape('Escaped? <.>');
// -> 'Escaped\?\ <\.>'

有关更多信息:http : //xregexp.com/api/#escape

不仅要转义会导致正则表达式出现问题的字符(例如:黑名单),还不考虑使用白名单。这样,除非每个字符都匹配,否则每个字符都会被视为已污染。

对于此示例,假定以下表达式:

RegExp.escape('be || ! be');

这会将字母,数字和空格列入白名单:

RegExp.escape = function (string) {
    return string.replace(/([^\w\d\s])/gi, '\\$1');
}

返回值:

"be \|\| \! be"

这可以使不需要转义的字符转义,但这不会妨碍您的表情(也许会受到一些时间上的惩罚-但出于安全考虑,这是值得的)。

escapeRegExp = function(str) {
  if (str == null) return '';
  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};

另一种(更安全)的方法是使用unicode转义格式转义所有字符(而不仅仅是我们目前知道的一些特殊字符)\u{code}

function escapeRegExp(text) {
    return Array.from(text)
           .map(char => `\\u{${char.charCodeAt(0).toString(16)}}`)
           .join('');
}

console.log(escapeRegExp('a.b')); // '\u{61}\u{2e}\u{62}'

请注意,您需要传递u标志才能使此方法起作用:

var expression = new RegExp(escapeRegExp(usersString), 'u');

其他答案中的函数对于转义整个正则表达式是过大的(它们对于转义正则表达式的某些部分可能有用,这些正则表达式随后将被合并为更大的正则表达式)。

如果你逃避整个正则表达式,并用它完成后,报价是要么独立的元字符(.?+*^$|\),或者开始做某件事(([{)是所有你需要:

String.prototype.regexEscape = function regexEscape() {
  return this.replace(/[.?+*^$|({[\\]/g, '\\$&');
};

是的,令人失望的是,JavaScript没有这样的内置函数。

曾经有过而且将永远有12个元字符需要转义

才能视为文字。

无关紧要的是,将转义的字符串插入平衡的

regex包装器中并附加
该字符串是没有关系的。

使用此字符串替换

var escaped_string = oldstring.replace( /[\\^$.|?*+()[{]/g, '\\$&' );

有一个ES7提案RegExp.escape在https://github.com/benjamingr/RexExp.escape/,与可用填充工具https://github.com/ljharb/regexp.escape

基于被拒绝的ES提案的示例包括检查该属性是否已经存在(如果TC39退回其决定)。


码:

if (!Object.prototype.hasOwnProperty.call(RegExp, 'escape')) {
  RegExp.escape = function(string) {
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping
    // https://github.com/benjamingr/RegExp.escape/issues/37
    return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
  };
}

缩小代码:

Object.prototype.hasOwnProperty.call(RegExp,"escape")||(RegExp.escape=function(e){return e.replace(/[.*+\-?^${}()|[\]\\]/g,"\\$&")});

// ...
var assert = require('assert');
 
var str = 'hello. how are you?';
var regex = new RegExp(RegExp.escape(str), 'g');
assert.equal(String(regex), '/hello\. how are you\?/g');

还有一个 npm模块:https :
//www.npmjs.com/package/regexp.escape


可以安装它并按以下方式使用它:


npm install regexp.escape

要么

yarn add regexp.escape

var escape = require('regexp.escape');
var assert = require('assert');
 
var str = 'hello. how are you?';
var regex = new RegExp(escape(str), 'g');
assert.equal(String(regex), '/hello\. how are you\?/g');

在GitHub && NPM页面中,还描述了如何将shim / polyfill用于此选项。该逻辑基于return RegExp.escape || implementation;,其中实现包含上面使用的regexp。


NPM模块是一个额外的依赖项,但是它也使外部贡献者更容易识别添加到代码中的逻辑部分。¯\ (ツ)

本文地址:http://javascript.askforanswer.com/javascriptzhongshifoucunzairegexp-escapehanshu.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!