【问题标题】:Ignore String containing special words (Months)忽略包含特殊单词的字符串(月)
【发布时间】:2014-01-28 14:09:05
【问题描述】:

我正在尝试使用以下正则表达式查找字母数字字符串:

^(?=.*\d)(?=.*[a-zA-Z]).{3,90}$

字母数字字符串:字母数字字符串是至少包含一个数字和一个字母加上任何其他特殊字符的任何字符串,它可以是@ - _ [] () {} ç_ \ù %


我想添加一个额外的约束来忽略所有包含以下月份格式的字母数字字符串:

JANVIER|FEVRIER|MARS|AVRIL|MAI|JUIN|JUILLET|AOUT|SEPTEMBRE|OCTOBRE|NOVEMBRE|DECEMBRE|Jan|Feb|Mar|Apr|May|Jun|JUN|Jul|Aug|Sep|Oct|Nov|Dec|[jJ]anvier|[fF][ée]vrier|[mM]ars|[aA]vril|[mM]ai|[jJ]uin|[jJ]uillet|[aA]o[éû]t|aout|[sS]eptembre|[oO]ctobre|[nN]ovembre|[dD][eé]cembre

一种解决方案是实际匹配一个字母数字字符串。然后使用以下函数检查此字符串是否包含这些名称之一:

 vector<string> findString(string s)
    {
        vector<string> vec;
        boost::regex rgx("JANVIER|FEVRIER|MARS|AVRIL|MAI|JUIN|JUILLET|AOUT|SEPTEMBRE|OCTOBRE|NOVEMBRE|DECEMBRE|Jan|Feb|Mar|Apr|May|Jun|JUN|Jul|Aug|Sep|Oct|Nov|Dec|[jJ]anvier|[fF][ée]vrier|[mM]ars|[aA]vril|[mM]ai|[jJ]uin|[jJ]uillet|[aA]o[éû]t|aout|[sS]eptembre|[oO]ctobre|[nN]ovembre|[dD][eé]cembre
");
        boost::smatch match;

        boost::sregex_iterator begin {s.begin(), s.end(), rgx},
              end {};

        for (boost::sregex_iterator& i = begin; i != end; ++i)
        {
            boost::smatch m = *i;
            vec.push_back(m.str());
        }

        return vec;
    }

问题:我怎样才能将这个约束直接添加到正则表达式中而不是使用这个函数。

一种解决方案是使用 How to ignore words in string using Regular Expressions 中提到的负前瞻。


我是这样使用的:

字符串:2-hello-001

正则表达式:^(?=.*\d)(?=.*[a-zA-Z]^(?!Jan|Feb|Mar)).{3,90}$

结果:不匹配

测试网站:http://regexlib.com/


@Robin 和@RyanCarlson 提供的编辑:^[][\w@_(){}ç\\ù%-]{3,90}$ 在检测带有特殊字符的字母数字字符串方面非常有效。只是消极的前瞻部分不起作用。

【问题讨论】:

  • 为什么需要^(?=.*\d)(?=.*[a-zA-Z]).{3,90}$?像^[a-zA-Z0-9]{3,90}$ 这样的东西不是更好吗?
  • 好吧,如果我想匹配以下字符串,请根据@RyanCarlson 的建议:555_tdstg--hani 我做不到。
  • 它也会匹配像a1"&amp;@^&amp;@?&lt;.?\]\[~@^@^`这样的字符串
  • 请定义(通过更新您的问题,以便每个人都清楚)您要匹配哪些特殊字符。
  • 你也想要空格吗?还有/?您应该对这些字符使用代码标记,我编辑了您的问题以尝试澄清这一点。

标签: c++ regex string


【解决方案1】:

您可以使用否定前瞻,就像使用积极前瞻一样:

(?=.*\d)(?=.*[a-zA-Z])
(?!.*(?:JANVIER|FEVRIER|MARS|AVRIL|MAI|JUIN|JUILLET|AOUT|SEPTEMBRE|OCTOBRE|NOVEMBRE|DECEMBRE|Jan|Feb|Mar|Apr|May|Jun|JUN|Jul|Aug|Sep|Oct|Nov|Dec|[jJ]anvier|[fF][ée]vrier|[mM]ars|[aA]vril|[mM]ai|[jJ]uin|[jJ]uillet|[aA]o[éû]t|aout|[sS]eptembre|[oO]ctobre|[nN]ovembre|[dD][eé]cembre)).{3,90}$

你的正则表达式也很不清楚。如果你想要长度在 3 到 90 之间的字母数字字符串,你可以这样做:

/^(?!.*(?:JANVIER|F[Eé]VRIER|MARS|AVRIL|MAI|JUIN|JUILLET|AO[Uù]T|SEPTEMBRE|OCTOBRE|NOVEMBRE|D[Eé]CEMBRE|Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))
[][\w@_(){}ç\\ù%-]{3,90}$/i

i 标志意味着它将匹配大小写(因此您可以减少禁止列表),\w 是[0-9a-zA-Z_] 的快捷方式(如果您复制粘贴要小心,这里有一个换行符以提高可读性在(?! ) 和[ ] 之间)。只需在最后的 [...] 中添加您想要匹配的任何特殊字符。

【讨论】:

  • @Robin \w 也匹配 _。
  • @Hani Goc:您的问题并不清楚。如果这些是您需要的唯一特殊字符,请参阅更新的答案。如果可能有更多(如标点符号、带重音符号的字符、空格...),请添加这些字符或使用[^ ] 匹配除这几个字符之外的任何内容。还要感谢@Ryan。
  • 再次更新答案,只需更新最终的[ ] 以匹配您想要的内容,您应该会很好。
  • goo.gl/i2uS17 对我来说很好用(你的链接只是指向主页,我看不到你在那里输入的任何内容:/)。我在stackoverflow上发布的代码中有一个换行符,以便在负前瞻和匹配之间具有可读性,你删除了吗?可能确实不明显。
  • 1) 对于至少一个数字:(?=.*\d)(对于字母数字 (?=[a-z0-9]))在正则表达式的开头。 2)i 标志是正则表达式语言,但也许您需要以不同于/regex/flags 的方式传递标志。一些正则表达式支持 (?i) 在正则表达式的开头,一些函数将正则表达式和标志作为两个不同的参数。您应该看到您正在使用正则表达式的函数的文档。
猜你喜欢
  • 1970-01-01
  • 2021-11-05
  • 2016-05-05
  • 1970-01-01
  • 2019-03-20
  • 1970-01-01
  • 1970-01-01
  • 2020-12-25
  • 2019-08-03
相关资源
最近更新 更多