【发布时间】:2023-03-31 21:55:01
【问题描述】:
要在 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 令牌和@987654333 @还有:
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 如果仅应用于default_pattern,则会生成此正则表达式
return this.trim(text.split(/((?:[^a-z0-9äâàéèëêïîöôùüûœç]+))/gi));
这会稍微改变默认模式的结果标记:
return this.trim(text.split(/[^a-z0-9äâàéèëêïîöôùüûœç]+/i));
【问题讨论】:
-
> 排除一些模式到默认模式 这行不清楚。你的意思是“用默认模式替换每个受保护的模式”?
-
@AlexanderMashin 抱歉,我的意思是避免将
default_pattern应用于excluded_patterns数组中的每个模式。这个概念取自 MOSES tokenizer protected patterns - github.com/moses-smt/mosesdecoder/blob/master/scripts/tokenizer/… -
您希望您的结果包含“la-la-la”,但您实际上将该字符串设置为分隔符。你的意思是“la-la-la”不能分成“la”吗?哦,是的,从您之前的评论中可以明显看出这一点。那么你的方法,用默认分隔符对“不可分割”模式进行 ORing,从根本上是错误的。
-
@AlexanderMashin 我希望
la-la-la会保留为一个完整的字符串。如果我这样做"salut comment allez-vous la-la-la".match(/\bla([- ]?la)+\b/g);,这将有效。这里的问题是关于以正确的方式组合模式和“受保护”模式。
标签: javascript regex tokenize