【问题标题】:RegEx for matching 3 alphabets and 1-2 digits用于匹配 3 个字母和 1-2 位数字的正则表达式
【发布时间】:2019-10-10 13:05:11
【问题描述】:

我正在尝试编写一个正则表达式来在至少有 100 个字符的文本中查找匹配项。匹配应该是这样的 - 字符串中的任何子字符串至少包含 3 个字母开头,后面至少有 1 个数字,3 个字母后面最多有 2 个数字。

示例 -

  1. abcjkhklfdpdn24hjkk - 在这种情况下,我想提取 pdn24

  2. hjdksfkpdf1lkjk - 在这种情况下,我想提取 pdf1

  3. hjgjdkspdg34kjfs dhj khk678jkfhlds1 - 在这种情况下,我想要 pdg34 和 lds1

如何为此编写正则表达式?匹配的起始字母长度始终为 3,数字长度可以是 1 或 2(不多不少)

如果 3 个字母的字符串后面有 2 个数字,这就是有效的。

[A-Za-z]{3}[0-9]{2}

但数字的长度可以在 1 和 2 之间变化。如何在正则表达式中包含不同的长度?

【问题讨论】:

  • 这 100 个字符应该提前用长度函数检查。要获得所有你想要的,只需要一个 findall 类型的函数或一个循环搜索函数。 (?i)[a-z]{3}\d{1,2}
  • “……至少 3 个字母开头……”有点令人困惑。从您的示例来看,我认为您只想匹配每个包含 3 个字母后跟 1 或 2 个数字的子字符串,而不是数字。
  • 是的,没错。每 3 个字母的子字符串后跟 1 或 2 个数字。

标签: regex ruby regex-lookarounds regex-group regex-greedy


【解决方案1】:

我们希望设计的表达式非常有趣。我们可以先在捕获组中添加您的原始表情并稍加修改,然后我们应该考虑它的左右边界。例如,在右边我们可能想使用\D

([A-Za-z]{3}[0-9]{1,2})\D

DEMO 1

我们当然可以定义一个精确的受限表达式。但是,这可能只是工作。


根据Cary Swoveland的建议,我们也可以使用这个表达式,这样会好很多:

\p{L}{3}\d{1,2}(?!\d)

测试

re = /([A-Za-z]{3}[0-9]{1,2})\D/m
str = 'abcjkhklfdpdn24hjkk
hjdksfkpdf1lkjk
hjgjdkspdg34kjfs dhj khk678jkfhlds1 '

# Print the match result
str.scan(re) do |match|
    puts match.to_s
end

这个脚本展示了捕获组是如何工作的:

const regex = /([A-Za-z]{3}[0-9]{1,2})\D/gm;
const str = `abcjkhklfdpdn24hjkk
hjdksfkpdf1lkjk
hjgjdkspdg34kjfs dhj khk678jkfhlds1 `;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

【讨论】:

  • "abc123".match? /([A-Za-z]{3}[0-9]{1,2})\D?/ #=> true,但应该为假,因为'1''12'后面不能跟数字。 \D? 无效。您不能删除问号,因为这将要求字符串以非数字结尾,这不是必需的。你想要的不是数字后面应该有什么,而是数字后面应该,即另一个数字。为此,您需要进行负面预测:(?!\d)。我也看不到捕获组的意义。试试"abcd12 efg345ghij21".scan /\p{L}{3}\d{1,2}(?!\d)/ #=> ["bcd12", "hij21"]
【解决方案2】:

至少 3 个字母:[a-zA-Z]{3,} 1 位或 2 位数字(不多不少):[0-9]{1,2}

这给了我们:

/[a-zA-Z]{3,}[0-9]{1,2}/

【讨论】:

  • 啊,但是如果这个匹配后面跟着另一个数字呢?应该是不匹配的。
猜你喜欢
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-10
  • 1970-01-01
  • 2021-01-10
  • 2010-09-15
  • 1970-01-01
相关资源
最近更新 更多