【问题标题】:regex to get "words" containing letters and (numbers/certain special), but not only numbers正则表达式获取包含字母和(数字/某些特殊)的“单词”,但不仅仅是数字
【发布时间】:2017-10-26 11:48:26
【问题描述】:

简而言之:我想匹配包含 1 个字母和至少 1 个(数字/某些特殊字符)的任何“单词”(由空格分隔的连续字符集)。这些“词”可以出现在句子的任何地方。

使用repython 中尝试此操作到目前为止,作为一种模式,我有:

\w*[\d@]\w*

这在大多数情况下有效;但是,我不希望只有数字/特殊的“单词”。例如:

应该匹配:

h1DF346
123FE453
3f3g6hj7j5v3
hasdf@asdf
r3
r@

不应匹配:

555555
@
hello
onlyletters

在“不应该匹配”下排除前两个时遇到问题。感觉这里缺少一些简单的东西。谢谢!

【问题讨论】:

  • 当您说 "word"(连续的字符集)_ 并使用 \w 时,它也将包含数字。正如\w 代表[a-zA-Z0-9_]。还要澄清哪些_某些特殊字符
  • 例如,我发布的模式中的@。应该至少有 1 个字母,AND(1 个数字或 1 个@#)——为了简单起见,我现在只是添加了 @ 示例——我不知道我完全需要哪些字符,但看到模式@ 应该足够了
  • 这些“词”是一行中唯一的东西,还是无处不在?
  • 可以出现在线上的任何地方。比如:“hello 123test world”应该得到 123test

标签: python regex


【解决方案1】:

我会使用| 或这样的运算符:

([A-Za-z]+[\d@]+[\w@]*|[\d@]+[A-Za-z]+[\w@]*)

你想要的意思:

  • 字母后跟数字@ 后跟任意组合,
  • 或数字@后接字母后接任意组合

Check the regex101 demo here

如果您在正则表达式的其他部分使用组,请考虑使用非捕获组 (?:...) 而不是 (...)

【讨论】:

  • 它比 Rahul 的答案需要更少的步骤,并且比 @Jan 的答案更多的步骤不起作用:P
  • @Jan 仍然失败:鉴于“Jan”与不应该匹配的“an”匹配 ;)
  • @Jan 匹配“123@”,这不应该:) 如果可以在我的答案之上做出 10 倍的改进,我会感到非常惊讶(并且渴望知道如何去做),因为或'ed 正则表达式应该在第一个字符上失败...
  • 解决方案 imo 是使第一个替代项 possessive,请参阅此示例,它匹配所有所需的单词,但保留其余单词 (338需要步骤):regex101.com/r/lBcGvU/5
【解决方案2】:

如果您只是将 *(匹配 0 或更多)更改为 +(匹配 1 或更多),则可以正确命中所有内容。

\w+[\d@]\w+

除了 5555... 字母和数字的分布是否还有其他可以区分的模式?您可以通过将 \w 替换为 [\d@] 之前或之后至少一个字母的要求来处理它吗?

【讨论】:

  • 它不会匹配应该匹配的“r@”
【解决方案3】:

使用这样的前瞻断言。

正则表达式: (?=.*[a-zA-Z])(?=.*[@#\d])[a-zA-Z\d@#]+

说明:

  • (?=.*[a-zA-Z]) 测试something or not 后面是否跟一个字母。

  • (?=.*[@#\d]) 测试something or not 后面是否跟给定字符类的一个字符。

  • [a-zA-Z\d@#]+ 匹配给定字符类中的一个或多个字符。

Regex101 Demo

【讨论】:

    【解决方案4】:

    虽然您有答案,但您仍然可以提高接受的正则表达式的速度:

    (?=\d++[A-Za-z]+[\w@]+|[a-zA-Z]++[\w@]+)[\w@]{2,}
    

    您将需要更新的 regex 模块:

    import regex as re
    
    string = "h1DF346 123FE453 3f3g6hj7j5v3 hasdf@asdf r3 r@ 555555 @ hello onlyletters"
    rx = re.compile(r'(?=\d++[A-Za-z]+[\w@]+|[a-zA-Z]++[\w@]+)[\w@]{2,}')
    print(rx.findall(string))
    # ['h1DF346', '123FE453', '3f3g6hj7j5v3', 'hasdf@asdf', 'r3', 'r@']
    

    劫持@Roberto 的演示,您将有一个significant reduction 在查找匹配项所需的步骤中(>7000 对 338,约 20 次)。

    【讨论】:

    • 有趣!以前没有听说过 SKIP/FAIL 并且肯定想对此进行更多研究。这个例子(但是)似乎也匹配任何以大写字母开头的单词
    • 它将匹配不应该的“@@@”
    • @NikT: 调整了,现在没有了(在你原来的帖子中仍然没有要求)。
    • 鉴于“NikT”与“ikT”不应该匹配:P
    • 它匹配不应该的“123@”;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2022-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多