用于提取实例ID,AMI ID,卷ID的正则表达式

时间:2016-08-12 10:27:55

标签: java regex

给出以下字符串

  

由CreateImage(i-b9b4ffaa)为vol-e97db305的ami-dbcf88b1创建

我希望能够使用正则表达式提取以下内容

  

的i-b9b4ffaa   AMI-dbcf88b1   体积-e97db305

这是我提出的正则表达式,目前不能满足我的需要:

Pattern p = Pattern.compile("Created by CreateImage([a-z]+[0.9]+)([a-z]+[0.9]+)([a-z]+[0.9]+)",Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("Created by CreateImage(i-b9b4ffaa) for ami-dbcf88b1 from vol-e97db305");
System.out.println(m.matches()); --> false

1 个答案:

答案 0 :(得分:1)

您可以匹配以字母开头的所有单词,后跟连字符,然后使用字母数字字符:

String s = "Created by CreateImage(i-b9b4ffaa) for ami-dbcf88b1 from vol-e97db305";
Pattern pattern = Pattern.compile("(?i)\\b[a-z]+-[a-z0-9]+");
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
    System.out.println(matcher.group(0)); 
} 
// => i-b9b4ffaa, ami-dbcf88b1, vol-e97db305

请参阅Java demo

模式详情

  • (?i) - 不区分大小写的修饰符(嵌入标记选项)
  • \\b - 字边界
  • [a-z]+ - 一个或多个ASCII字母
  • - - 连字符
  • [a-z0-9]+ - 一个或多个字母数字。

要确保这些值显示在Created by CreateImage 之后的同一行,请使用基于\G的正则表达式:

String s = "Created by CreateImage(i-b9b4ffaa) for ami-dbcf88b1 from vol-e97db305";
Pattern pattern = Pattern.compile("(?i)(?:Created by CreateImage|(?!\\A)\\G)(?:(?!\\b[a-z]+-[a-z0-9]+).)*\\b([a-z]+-[a-z0-9]+)");
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
    System.out.println(matcher.group(1)); 
} 

请参阅this demo

请注意,上述模式基于匹配上一次成功匹配结束的\G运算符(因此我们仅在匹配后或Created...之后匹配)和一个调和的贪婪令牌{{ 1}}(匹配除了不启动序列的换行符之外的任何符号:(?:(?!\\b[a-z]+-[a-z0-9]+).)* + word boundary + letters + -),这非常耗费资源。

您应该考虑使用两步法首先检查字符串是否以letters|digits字符串开头,然后处理

Created...

请参阅another demo