我正在研究一种NLP功能,该功能可以处理带有单位的句子。 (例如,“向我展示我的300克以上项目是在2012年10月10日之后在30公里半径内开始的”)
我需要对字符串进行预处理,以将“ 300g”更改为“ 300 g”,将“ 30km”更改为“ 30 km”,以便可以将其视为两个单独的值/单词。
我的代码在Node.js中。
我的第一个解决方案是:
str = "Show me my projects above 300g started after the 10/10/2012 in a 30km radius";
result = str.match(/(\d+|[^\d]+)/g).join(' ');
result => "Show me my projects above 300 g started after the 10 / 10 / 2012 in a 30 km radius"
我的问题是日期也被分割了,我需要它们保持完整才能被检测为日期。
我不想将格式日期与空格匹配,然后再删除空格,因为这可能会更改用户输入(如果我们删除空格,用户可能会输入一个数学方程式,该数学方程式可能会误认为是日期。) “ 3 * 10-10-2016 + 42”将变为“ 3 * 10-10-2016 + 42”)
这有点牵强,但是不添加空格而不是删除我错误添加的空格似乎更加安全。
我打算做的是将我的字符串分割成一个数组,日期与其余部分分开:
["Show me my projects above 300g started after the ", "10/10/2012", "in a 30km radius"]
然后执行str.match(/(\ d + | [^ \ d] +)/ g).join('');不是日期的元素上。 不幸的是,我找不到一种以这种方式拆分字符串的方法。我尝试了以下正则表达式:
str = "Show me my projects above 300g started after the 10/10/2012";
result = str.match(/(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})|([^\d{1,2}[/-]\d{1,2}[/-]\d{2,4}])/g);
但是语法不正确(如此处所示:https://regexr.com/3s9m8) 我不知道如何匹配非日期部分,因为[^ ...]不适用于复杂的语句。
是否有一种方法可以执行该正则表达式,或者我需要找到一种不同的方法来做到这一点?
预先感谢, 蒂博。
答案 0 :(得分:2)
有两个解决方案。您可以给出要分割的后缀列表,也可以只是确保将字母分开即可。
/(\d+)(g|kg|m|km)/g
将是后缀列表的开始
/(\d+)([A-Z])/ig
将基于拆分字母
然后我建议使用简单的替换功能进行预处理。
const string = "Show me my projects above 300g started after the 10/10/2012 in a 30km radius";
console.log(string.replace(/(\d+)([A-Z])/ig, "$1 $2"));
您也可以使用积极的前瞻方式来简化替换功能。
const string = "Show me my projects above 300g started after the 10/10/2012 in a 30km radius";
console.log(string.replace(/(\d+)(?=[A-Z])/ig, "$1 "));