给出以下字符串
由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
答案 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