我有一个文本文件,我用以下语法存储证书:
-----BEGIN CERTIFICATE-----
Certificate is in here. It's a really long string of characters and looks like garbage. Each certificate is variable length.
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
Another certificate is in here
-----END CERTIFICATE-----
然后,我有代码,我尝试阅读上面的文本文件,并逐个检查每个证书。
//This copies all of my certificates from a file into a String
String certificates = new Scanner(new File("certificates.txt"), "UTF-8").useDelimiter("\\A").next();
//This creates a pattern so that I can examine each certificate one at a time
//(?s) allows this pattern to span several lines.
Pattern pattern = Pattern.compile("(?s)-----BEGIN CERTIFICATE-----.*-----END CERTIFICATE");
Matcher matcher = pattern.matcher(certificates);
//I attempt to examine each certificate one at a time
while(matcher.find())
{
System.out.println(matcher.group());
}
但是,当我调用matcher.find()时,它会返回整个证书文件。我认为因为它在文件的开头找到“----- BEGIN CERTIFICATE -----”,然后在文件末尾找到“----- END CERTIFICATE -----”
如何更改正则表达式模式以便顺序查找每个证书?
答案 0 :(得分:3)
原因是.*
是greedy表达式,它匹配尽可能多的证书部分。您可以通过添加?
量词使用不情愿的表达式将此匹配限制为单个部分:
Pattern pattern =
Pattern.compile("(?s)-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE");
答案 1 :(得分:1)
如果您使用以下作为示例:
-----BEGIN CERTIFICATE-----
asAasdfO'Psadf-ASDFgrvd-dK;9twqegvb5wetg5089'O0'[U'P4we5AASDSFDevbF54wgwe54-t4g5g54wgsefe4-
-----END CERTIFICATE-----
然后,以下正则表达式需要242个步骤来拉动,并且如果证书更长,它将迅速增长:
(?s)-----BEGIN CERTIFICATE-----.*-----END CERTIFICATE
242不是很多,但话说再来一次,这是一个非常小的证书。我见过证书很长。我不确定这种影响会不会对你造成太大伤害。但是,以下正则表达式只需要72步,无论证书有多长,它总是大约72步:
(-{5})BEGIN\sCERTIFICATE\1\s*(?<Cert>[^-]*(?:(?=\1)|-))*?\s*\1END\sCERTIFICATE\1
看起来可能更复杂。但在谈到Regex时,它非常清楚。此外,它不会包括Begin之后和End之前的换行符。只需拔出Matcher.Group(“Cert”)以获取证书。
击穿: 首先,匹配五个破折号。将其设置为Capture Group 1以便以后使用。 匹配“BEGIN CERTIFICATE”。正则表达式中的空格很难看,应该是[]或\ s。 使用\ s(5个破折号)调用Capture Group 1。 使用\ s *修剪空格,包括换行符 在证书组中,一次性捕获文本集(不是懒惰),直到后面跟着五个虚线。 (这是递归的)。 匹配任何空格(包括换行符),五个破折号,END CERTIFICATE和五个破折号。