我可以让常规表达式的负向后顾断言应用于整个表达式吗?

2 投票
2 回答
2044 浏览
提问于 2025-04-16 23:33

我正在用Python的 re 模块尝试写一个正则表达式,目的是找到所有不以感叹号(!)开头的驼峰命名法的单词。

这是我目前的代码:

(?<![!])([A-Z]?[a-z]+[A-Z][a-zA-Z]+)

我发现负向前瞻断言只应用在第一个 [A-Z] 的部分,而不是我想象中的整个括号里的内容。有没有办法让这个负向前瞻断言作用于整个组呢?

如果不行,有没有其他建议可以让我解决这个问题?

我需要匹配(并最终替换)所有的驼峰命名法单词。我对驼峰命名法的定义如下:

  1. 任何以一个大写字母或小写字母开头的单词
  2. 后面跟一个或多个小写字母
  3. 再跟一个大写字母
  4. 最后再跟一个或多个小写字母

换句话说,就是任何以仅一个大写字母开头,后面跟着一个或多个小写字母,再接一个大写字母,最后再跟一个或多个小写字母的单词。

这些都很好匹配,但问题在于我需要检查这个单词是否以感叹号(!)开头。我的目标是找到所有不以这个符号开头的单词。

举个例子:

  • 这个正则表达式应该匹配: HelloWorld
  • 这个正则表达式不应该匹配: !HelloWorld

在这样的句子中:“欢迎来到 MyWorld!我们这里有 !CoolStuff!”我应该能提取出 MyWorld,但不能提取 CoolStuff。

谢谢你的帮助,
-Sunjay03

[编辑:] 这是一个不工作的字符串:

"This is an example of !HelloWorld. Click that link FOO! Also, check out my iPods"

这个正则表达式提取出的内容是:

['elloWorld', 'iPods']

解决方案: (?<![!])\b([A-Z]?[a-z]+[A-Z][a-zA-Z]+)

感谢 JBernardo 的建议。这个解决方案之所以有效,是因为它寻找的是不包括感叹号的单词边界。

2 个回答

1

看起来下面的代码可以满足你的需求,

>>> reg=r'[^!]\b([a-zA-Z][a-z]+[A-Z][a-zA-Z]+)\b'
>>> text="Welcome to MyWorld! We have !CoolStuff here YouAgree?"
>>> re.findall(reg, text)
['MyWorld', 'YouAgree']
>>> 
3
re.findall(r'(?<![!])\b\w+', ' !Hai  Yo!')

结果是 ['Yo']

顺便说一下,只要把 \w+ 换成你自己的验证规则,但要记得保留 \b

撰写回答