【问题标题】:A Regex to ignore a set of words忽略一组单词的正则表达式
【发布时间】:2020-06-25 13:53:26
【问题描述】:

有没有办法设置正则表达式来忽略一组由空格分隔的单词?

我有不同的产品名称,例如: “矩阵 10X,10 毫升 + 分配器” 数量不等的“Matrix 10X,10ml + DISPENSER”

我想要做的是使用正则表达式替换所有单词,除了: "10 毫升" | “10 毫升” | “10ml” ---> 这些都可以忽略

我找到了一个代码来替换除以空格分隔的单词以外的所有字符(例如“10 ml”) https://regex101.com/r/bG8vB4/5

并在它们在一起时替换它们(例如“10ml”)

https://regex101.com/r/bG8vB4/4

但可以找到一种方法将它们混合在一起以仅保留“10 ml”或“10 ML”或“10ml”并删除字符串末尾的其他字符

【问题讨论】:

  • 你可以匹配这些单词(?i)\b10\s*ML并跳过(?i)\b10\s*ML(*SKIP)(*F)然后匹配其他“单词”(?i)\b10\s*ML(*SKIP)(*F)|\S+

标签: regex word


【解决方案1】:

正则表达式是一种用于对字符串进行高效计算机识别的数学模型。就像得到一个正则表达式来匹配一个字符串(如果它有 any 一些单词)一样简单,数学表明,如果它没有这些单词,那么正则表达式获取一个匹配字符串的字符串匹配器是可能的。获得这样一个正则表达式的方法虽然要复杂得多。

在正则表达式理论中,正则语言是一种允许您从正则表达式设置有限自动机的语言,并且如果原始字符串不识别字符串的自动机只需将所有接受状态切换为非接受国家。完成此操作后,最困难的部分是构建一个与该自动机匹配的正则表达式(这是可能的,但最终的正则表达式通常比原来的要复杂得多)这可以通过一个示例来解决(一个简单的)你会发现这是一件复杂的事情(当然,一些正则表达式库允许你为此使用操作数,但你没有指定你正在使用的是否有)一个这样的示例是当你必须识别一个简单的 C 语言注释。注释是由序列/**/ 分隔的字符串,但在内部,不能有序列*/

第一种方法可能是使用以下正则表达式:

\/\*.*\*\/

但这失败了,因为内部正则表达式包括对 */ 的识别作为它的一部分,所以 /* bla bla bla */ bla bla bla */ 将被识别为整个评论(它应该在第一个 */ 结束)所以我们需要一个正则表达式可识别任何内容,但不包括 */

这样的子表达式是:

([^*]|\*[^/])*

这意味着与* 不同的字符的不确定连接,或者包括第一个字符为* 的序列后面没有/。如果您遵循该串联,您会发现不可能形成一个序列*/ 导致我们的最终正则表达式:

\/\*([^*]|\*[^/])*\*\/

(现在你明白事情有多复杂了)

要将其扩展到单个单词(如word,超过两个字母),您必须考虑您可以允许:

([^w]|w[^o]|wo[^r]|wor[^d])*

在集合中,如果你有两个词(如foobar),你必须写:

([^f]|f[^o]|fo[^o]|[^b]|b[^a]|ba[^r])*

意味着对于每个单词你都有这样的正则表达式,使最终的正则表达式有点复杂。此外,如果某些词可以是另一个词的前缀,或者某些词具有相同的前缀字符,则词之间可能会发生交互。这也可能存在将正则表达式编译成有限自动机的问题,产生了许多将| 运算符视为非交换的库并以非交换的方式解决它们,从而导致错误的结果。

您还没有解释忽略的含义。如果您的意思是匹配它们并传递,则与忽略它们可能出现的整行不同。那么正则表达式(您需要解决的问题的定义完全不同 --- 我的解释是拒绝一个完整的句子,如果它上面有 any 的单词,这可能不是你的意思)所以请解释(在你的问题中)你的意思是什么:

  • 接受您已匹配包含单词的句子。
  • 拒绝这样的句子。
  • 您完全拒绝(或忽略)什么。

只拒绝一个词,就是选择一个包含该词的句子,并标记该词以使其能够通过它。但这是一个不同的问题,它需要选择确实有这个词的句子

【讨论】:

    猜你喜欢
    • 2013-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    相关资源
    最近更新 更多