我不清楚您的实际输入和输出应该是什么。这是一个猜测。像
这样的输入
[{
sample: 'covid-19 testing status upto may 05,2021',
extract: 'may 05,2021',
propName: 'date'
}, {
sample: 'Jack and Jones are friends',
extract: 'Jones',
propName: 'friend-name'
}]
我们生成一个可以这样使用的函数:
mySubs ('Jack and William are friends')
//=> {"friend-name": "William"}
或
(mySubs ('covid-19 testing status upto apr 30,2021')
//=> {"date": "apr 30,2021"}
或
mySubs ('Jack and Jessica are friends who dicsussed covid-19 testing status upto apr 27,2021')
//=> {"date": "apr 27,2021", "friend-name": "Jessica"}
如果没有匹配项,则会产生一个空对象。
我们通过为我们的样本动态生成正则表达式来做到这一点,这些表达式将捕获所做的替换:
const regEscape = (s) =>
s .replace (/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
const makeTester = ({sample, extract, propName}) => ({
regex: new RegExp (
regEscape (sample .slice (0, sample .indexOf (extract))) +
'(.+)' +
regEscape (sample .slice (sample .indexOf (extract) + extract .length))
),
propName
})
const substitutes = (configs, testers = configs .map (makeTester)) => (sentence) =>
Object.assign( ...testers .flatMap (({regex, propName}) => {
const match = sentence .match (regex)
return (match)
? {[propName]: match[1]}
: {}
}))
const configs = [{
sample: 'covid-19 testing status upto may 05,2021',
extract: 'may 05,2021',
propName: 'date'
}, {
sample: 'Jack and Jones are friends',
extract: 'Jones',
propName: 'friend-name'
}]
const mySubs = substitutes (configs)
console .log (mySubs ('Jack and William are friends'))
console .log (mySubs ('covid-19 testing status upto apr 30,2021'))
console .log (mySubs ('Jack and Jessica are friends who dicsussed covid-19 testing status upto apr 27,2021'))
console .log (mySubs ('Some random string that does not match'))
.as-console-wrapper {max-height: 100% !important; top: 0}
如果您还需要报告匹配的模板,您可以为每个模板添加一个名称,然后通过两个主要函数将结果携带到这样的结果:
{"covid": {"date": "apr 27,2021"}, "friends": {"friend-name": "Jessica"}}
只是稍微复杂一点:
const regEscape = (s) =>
s .replace (/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
const makeTester = ({name, sample, extract, propName}) => ({
regex: new RegExp (
regEscape (sample .slice (0, sample .indexOf (extract))) +
'(.+)' +
regEscape (sample .slice (sample .indexOf (extract) + extract .length))
),
propName,
name
})
const substitutes = (configs, testers = configs.map(makeTester)) => (sentence) =>
Object.assign( ...testers .flatMap (({name, regex, propName}) => {
const match = sentence .match (regex)
return (match)
? {[name]: {[propName]: match[1]}}
: {}
}))
const configs = [{
name: 'covid',
sample: 'covid-19 testing status upto may 05,2021',
extract: 'may 05,2021',
propName: 'date'
}, {
name: 'friends',
sample: 'Jack and Jones are friends',
extract: 'Jones',
propName: 'friend-name'
}]
const mySubs = substitutes (configs)
console .log (mySubs ('Jack and William are friends'))
console .log (mySubs ('covid-19 testing status upto apr 30,2021'))
console .log (mySubs ('Jack and Jessica are friends who dicsussed covid-19 testing status upto apr 27,2021'))
console .log (mySubs ('Some random string that does not match'))
无论如何,这都有一些限制。如果模板以奇怪的方式重叠等,很难弄清楚该怎么办。您也可能只想匹配完整的句子,而我的双重匹配示例没有意义。如果是这样,您可以在传递给new RegExp 的字符串前面加上一个'^' 并附加一个'$'。
同样,这是对您的要求的猜测。这里重要的是您可以动态生成正则表达式以供使用。