【问题标题】:RegEx to match words exactly n characters long but also contain a specific letter?正则表达式完全匹配 n 个字符长但还包含特定字母的单词?
【发布时间】:2020-09-01 08:21:44
【问题描述】:

我有一长串小写国家(例如巴厘岛、英国等)

如何匹配其中所有正好有 9 个字母长并且还包含字母“i”的单词?

到目前为止,我已经完成了第一部分:

\b\w{9}\b

感谢您的任何建议。

编辑:

所以我能够做到这一点:

\b(?=.*i.*)\w{9}\b

但它不适用于grep -E '\b(?=.*i.*)\w{9}\b' countries.txt... 我做错了什么?

【问题讨论】:

  • 如果没有空格,Paul 的响应可以正常工作。圣马力诺(9 个字母 + 空格,总共 10 个)和斯里兰卡(8 个字母和一个空格,总共 9 个)这样的国家应该怎么办?其中任何一个也应该匹配吗?
  • 您使用的是哪个环境?你有错误吗?是否支持正向前瞻?
  • -E 表示 ERE,它不支持环视、非贪婪等...如果您使用的是 GNU grepPCRE 可用,那么试试,grep -wP '(?=\w*i)\w{9}' (但它不适用于有空格等非单词字符的国家/地区)
  • 要使用长度为 9 个字符且包含 i 的单词字符匹配单个单词,您可以使用 grep -Po '\b(?=\w{9}\b)\w*i\w*\b'
  • 您在提问时需要提供更多详细信息。例如,我无法判断 - 是否每行显示一个国家/地区?还是单行?当国家名称可能包含非字母,如空格或连字符(例如几内亚比绍)时,“九个字母”是什么意思?

标签: regex grep match contains


【解决方案1】:

您可以使用正向前瞻来检查字符数,然后检查其中是否有 i。

(?=^[\w\s]{9}$).*i.*

【讨论】:

  • 这很好用,除非国内有空位。我在问题中问过这个问题(我不知道空格是否算作字母)。
  • 谢谢,确实如此!我现在允许空白字符。如果开头或结尾有空格,这实际上将无法正常工作,但是由于它是一个列表,因此它可能已被修剪并且无关紧要。如果允许“任何字符”,它甚至可能在这种情况下工作。
  • 您如何确定输入文件每行显示一个国家/地区?
  • 因为克兰菲尔德在谈论一长串名单。它们显然没有被空格隔开,否则就无法过滤像英国这样的国家。在任何其他情况下,可以分别处理每个国家/地区。
【解决方案2】:

如果你不能匹配一个单一的正则表达式,你应该尝试两个或更多。在此语句中,grep 检查长度和一般字符,然后检查 i。

grep -E '(\w|\s){9}' regex.txt | grep -E 'i'

如果您正在寻找更严格的要求:

grep -E '(\w|\s){9}' regex.txt | grep -E 'i' | grep -E '\w+(\s\w+)*'

【讨论】:

  • 现在字母 i 是可选的,所以它仍然匹配没有它的国家/地区。
  • 我在开头添加了'i'
  • 我在上面编辑了我的评论。请在发布答案之前至少进行最低限度的验证。
  • 你的执行力很差。例如,当前版本有一个交替,和量词{9},但量词只适用于九个空格,而不适用于九个单词字符。正则表达式还必须锚定在单词边界处。但是,这些都不会影响正确的方法:管道两个 grep 调用,它们几乎同时在流上工作。折磨正则表达式以将两个要求都塞进一个正则表达式是没有意义的。为正确的方法 +1。
  • @mathguy 我检查了“斯里兰卡”,一切顺利; 'Sri Lanka' 字符串没有 9 个空格,因此字符限制适用于整个交替。如果我想写一个更严格的正则表达式,我必须写一个非常复杂的正则表达式,因为国家没有像汽车平台、电子邮件或 IP 地址这样定义明确的模式。我假设输入文件包含一个写得很好的国家列表。感谢您的评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多