【问题标题】:Cannot tokenize string in JavaScript keeping all punctuation symbols无法在 JavaScript 中标记字符串,保留所有标点符号
【发布时间】:2018-03-06 12:33:28
【问题描述】:

我正在尝试将基于 JavaScript 中的正则表达式:/[\w'-]+|[^\w\s]+/g 的字符串标记化为带有适当标点符号的相应单词。

我的 RegEx 在这些用例中失败:

let text = `Hello-world.`;
let text2 = `I'm Kunal`;
let text3 = `... that Manhattan vegetarian restaurant Dirt Candy is "waging war on the 'eat your vegetables' mind-set"?`;


console.log(JSON.stringify(text.match(/[\w'-]+|[^\w\s]+/g), undefined, 4));
console.log(JSON.stringify(text2.match(/[\w'-]+|[^\w\s]+/g), undefined, 4));
console.log(JSON.stringify(text3.match(/[\w'-]+|[^\w\s]+/g), undefined, 4));

我的正则表达式在这些情况下失败:


总而言之,我无法对某些字符进行标记,例如:-'?. 和其他类似的字符,而我的正则表达式在上述用例中被打破。

编辑:

标点符号与英语共享,其中大部分是:

  • . -> 期间
  • , -> 逗号
  • ! -> 感叹号
  • ? -> 问号
  • : -> 冒号
  • ; -> 分号
  • ~ -> 波浪号
  • - -> 连字符
  • - -> 破折号
  • & -> & 符号
  • ... -> 省略号
  • "" -> 双引号
  • '' -> 单引号
  • [ and ] -> 括号
  • { , } -> 大括号
  • ( and ) -> 括号
  • | -> 水平线
  • \ and / -> 正斜杠和反斜杠
  • * -> 星号
  • ^ -> 插入符号
  • $ -> 美元符号
  • # -> 井号/井号
  • @ -> 在符号处

所以拆分规则是:在词尾和上面提到的标点处拆分字符串。


我还想将转义序列过滤为单个标记。

这是我的解决方案的fiddle

【问题讨论】:

  • 您的意思是您需要将特殊字符匹配为单个标记吗? /[\w'-]+|[^\w\s]/g?
  • 不,它只是没有在标点符号处拆分,例如:hello-world. 标记化的输出必须是:[hello-world.] 全部拆分标点符号而不是替换它们。看看上面的表格。
  • @WiktorStribiżew 是的,我想将它们作为单个令牌进行匹配。
  • 那你只需要/\w+|[^\w\s]/g
  • @WiktorStribiżew 你能解释一下你在回答中使用正则表达式的方法吗?

标签: javascript regex ecmascript-6


【解决方案1】:

你可以使用

/\\[^]|\.{3}|\w+|[^\w\s]/g

请参阅regex demo

详情

  • \\[^] - 匹配 \ 后跟任何字符
  • | - 或
  • \.{3} - 匹配 3 个点
  • | - 或
  • \w+ - 匹配一个或多个单词字符(字母、数字或_
  • | - 或
  • [^\w\s] - 匹配除单词和空格字符以外的任何字符。

JS 演示:

let text = `Hello-world.`;
let text2 = `I'm Kunal`;
let text3 = `... that Manhattan vegetarian restaurant Dirt Candy is "waging war on the 'eat your vegetables' mind-set"?`;
let text4=`abc_def`;
let text5=`Hello\\nWorld`;

console.log(text.match(/\\[^]|\.{3}|\w+|[^\w\s]/g));
console.log(text2.match(/\\[^]|\.{3}|\w+|[^\w\s]/g));
console.log(text3.match(/\\[^]|\.{3}|\w+|[^\w\s]/g));
console.log(text4.match(/\\[^]|\.{3}|\w+|[^\w\s]/g));
console.log(text5.match(/\\[^]|\.{3}|\w+|[^\w\s]/g));

【讨论】:

  • 对于这个输入:Hello \n World 它的失败,它的分裂"\"nWorld
  • @KunalMukherjee 是的,它是正确的。应该是这样的acc。根据您的逻辑:您将单词字符与非单词字符分开。如果你有一个换行符,它将被拆分(即它会在结果中丢失)。
  • 但我也想将转义序列过滤为单个标记。
  • 是的,这就是我要找的比赛。非常感谢。
  • :) 我刚刚意识到您将问题编辑为要求将Hello \nWorld 拆分为两个标记,但如果您使用/\\[^]|\.{3}|\w+|[^\w\s]/g\n 将成为结果数组的一部分。请具体。了解您真正需要的内容后,我将编辑答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 2021-04-14
  • 2011-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多