0

我有一个文本文件,我在其中使用以下语法存储证书:

-----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-----” .

如何更改我的正则表达式模式以便它按顺序找到每个证书?

4

2 回答 2

3

原因是这.*是一个匹配尽可能多的证书部分的贪婪表达式。您可以通过添加?量词使用不情愿的表达式将此匹配限制为单个部分:

Pattern pattern = 
   Pattern.compile("(?s)-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE");
于 2013-04-08T17:16:41.073 回答
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 以便以后使用。匹配“开始证书”。正则表达式中的空格很难看,应该是 [ ] 或 \s。使用 \s(5 个破折号)调用 Capture Group 1。修剪空格,包括带有 \s* 的换行符 在证书组中,一次捕获所有文本集(不要懒惰),直到后面跟着五个破折号。(这是递归的)。匹配任何空格(包括换行符)、五个破折号、END CERTIFICATE 和五个破折号。

于 2013-04-08T19:06:49.500 回答