javascript - JavaScript 正则表达式在组合正则表达式时添加受保护的模式
问题描述
要在 JavaScript 中组合一个或多个正则表达式模式,我使用以下函数:
Tokenizer.prototype.combinePatterns = function() {
return new RegExp('(' + [].slice.call(arguments).map(function (e) {
var e = e.toString()
return '(?:' + e.substring(1, e.length - 1) + ')'
}).join('|') + ')', "gi")
};
这工作正常。现在我想“保护”一些模式,这意味着我想在执行生成的正则表达式时排除一些模式。这意味着我希望default_pattern
不应用于protected_patterns
数组中定义的任何模式(这个概念取自MOSES Tokenizer protected patterns 选项)。
这些受保护的模式可能会或不会在默认模式中定义:
AggressiveTokenizer.prototype.tokenize = function(text, params = {}) {
var options = {
default_pattern: /[^a-z0-9äâàéèëêïîöôùüûœç]+/,
protected_patterns: []
};
for (var attr in params) options[attr] = params[attr];
var patterns = [].concat(options.protected_patterns).concat(options.default_pattern);
// LP: pass along all regex patterns as argument
patterns = this.combinePatterns.apply(this,patterns);
// break a string up into an array of tokens by anything non-word
return this.trim(text.split(patterns));
};
按照这种方法,假设保护一些模式,如
[ '\bla([- ]?la)+\b']
我从方法的结果中得到了这个组合的正则表达式combinePatterns
:
/((?:la([- ]?la)+)|(?:[^a-z0-9äâàéèëêïîöôùüûœç]+))/gi
结果不符合预期,因此例如在(法语)文本中具有salut comment allez-vous la-la-la
,虽然我得到了la-la-la
整个所需的令牌,但我得到了undefined
令牌,还有 a la-
:
var combinePatterns = function() {
return new RegExp('(' + [].slice.call(arguments).map(function(e) {
var e = e.toString()
return '(?:' + e.substring(1, e.length - 1) + ')'
}).join('|') + ')', "gi")
};
var tokenize = function(text, params = {}) {
var options = {
default_pattern: /[^a-z0-9äâàéèëêïîöôùüûœç]+/,
protected_patterns: []
};
for (var attr in params) options[attr] = params[attr];
var patterns = [].concat(options.protected_patterns).concat(options.default_pattern);
// LP: pass along all regex patterns as argument
patterns = this.combinePatterns.apply(this, patterns);
// break a string up into an array of tokens by anything non-word
return text.trim().split(patterns);
}
var text = "salut comment allez-vous la-la-la";
var res = tokenize(text, {
protected_patterns: ['\bla([- ]?la)+\b']
})
console.log(res)
我的预期结果应该是
[
"salut",
"comment"
"allez"
"vous"
"la-la-la"
]
出了什么问题:受保护的模式组合方法或protected_patterns
数组中的正则表达式?
提示:我注意到,combinePatterns
if 仅应用于default_pattern
生成的这个正则表达式
return this.trim(text.split(/((?:[^a-z0-9äâàéèëêïîöôùüûœç]+))/gi));
这会稍微改变默认模式的结果标记:
return this.trim(text.split(/[^a-z0-9äâàéèëêïîöôùüûœç]+/i));
解决方案
let tokenize = function( str, preserve ) {
const separators = /[^a-z0-9äâàéèëêïîöôùüûœç]+/i;
// Convert the array of preserved patterns into one RegExp:
const screen = new RegExp( '(?:' + preserve.map( s => '(?:' + s + ')' ).join( '|' ) + ')' );
// Screening delimiter. Must not be split by separators:
const scr = 'SSS';
// Regular expression for unscreening:
const scr_regex = new RegExp( scr + '(\\d)' + scr );
// Initialise the array of preserved substrings:
let screened = [];
return str
// Temporarily screen preserved patterns:
.replace( screen, s => scr + (screened.push( s ) - 1) + scr )
// Split into tokens:
.split( separators )
// Restore screened substrings in each token:
.map( s => s.replace( scr_regex, (_, i) => screened[parseInt( i )] ) );
};
let text = 'salut comment allez-vous la-la-la';
let res = tokenize( text, ['\\bla(?:[- ]?la)+\\b'] );
console.log( res );
推荐阅读
- dart - Dart - 即使条件为假也会执行 if 语句
- android - 通知广播接收器在活动中不工作
- javascript - 将 VueJs 组件添加到 Django 模板中
- javascript - 如何在nodeJs + sequelize + graphql中的s3存储桶上上传之前获取文件大小?
- nlp - 难以理解 Roberta 模型中使用的分词器
- javascript - 如何在graphql中返回函数/行错误
- html - 如何更改 JSX 中的自定义变量以传递给 CSS var()?
- python - 如何使用 sympy 替换直线方程中的一个点
- vercel - 如何解决 ZEIT NOW 部署错误 Error: Exited with 1
- sql - postgresql - 从 video_call 表中查找保留