Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Java字符串解析文本_Java_Regex - Fatal编程技术网

从Java字符串解析文本

从Java字符串解析文本,java,regex,Java,Regex,我有一个以下格式的字符串:-开始消息------,后跟可变长度的加密会话密钥,后跟换行符,后跟加密消息,后跟换行符,后跟数字签名,后跟------结束消息------ 解析这三条信息(会话密钥、加密消息和数字签名)的最佳方法是什么 我试着使用Scanner类,但我不知道用什么作为delimeter。我也尝试过使用Pattern类,但也无法找到该方法。谢谢大家! 新行 并从第一个值中删除----开始消息---,从最后一个值中删除----结束消息--- String[] parts = string

我有一个以下格式的字符串:-开始消息------,后跟可变长度的加密会话密钥,后跟换行符,后跟加密消息,后跟换行符,后跟数字签名,后跟------结束消息------

解析这三条信息(会话密钥、加密消息和数字签名)的最佳方法是什么

我试着使用Scanner类,但我不知道用什么作为delimeter。我也尝试过使用Pattern类,但也无法找到该方法。谢谢大家!

新行

并从第一个值中删除
----开始消息---
,从最后一个值中删除
----结束消息---

String[] parts = string.split("\r?\n");
sessionKey = parts[1];
encryptedMessage = parts[3]; 
digitalSignature = parts[5]; 

\r?
允许Windows EOL(
\r\n
)或Unix EOL(
\n
)。

对,请按Sergii所说删除开始和结束。然后对“\s+”执行正则表达式拆分 e、 g.在.NET中:

Regex.Split(Regex.Replace(strCert, "(?i)\s*-{5}(BEGIN|END)\sMESSAGE-{5}\s*", ""), "\s+")
也就是说,假设您的示例在每个数据体中都有单换行符的唯一原因是用于格式化,因为据我所知,这些换行符在实际证书中不存在。实际证书如下所示:

-----BEGIN MESSAGE-----
SNyeWtz8QD8AKdioMG11wu7U6gG2wD9tekvVrx6VYW+6oJj4Wl8NE+7i5MHbu4Au+vN1Z886lOWka7ekgPF8N7t9MpiFo2pBPHuFcOsaY5ETYuEyk5gaX7BYP7qT6wKGBRILmX6DblWqGxG2tKs/AdcHDqQ5QBXrP03uhN68wgo=

U2FsdGVkX18gtpQSqyH4H5242SZzcZrb0oH7FWw7/MSCxo7h7BVaesZV2N38sr9y

kVr+wabiNn4RfAB4nNi9gAZHQLok4uxRMALGF2kZk2zpVNPQo6jcdz85fy68gylXOCQIIdk8JPIwxzHfVvRZqNHDRADZRlNHUMYScjRPU+DB8avghYAVKMJhLgA/2Tdpa59uBMBg/yB1yqA5FivxPzOhq92Y4nZuP1R9/yGE9O8K
-----END MESSAGE-----
是吗?

代码:

public class MessageParser {

   public static void main( String[] args ) {
      String message =
         "-----BEGIN MESSAGE-----\n" +
         "SNyeWtz8QD8AKdioMG11wu7U6gG2wD9tekvVrx6VYW+6oJj4Wl8NE+7i5MHbu4Au\n" +
         "+vN1Z886lOWka7ekgPF8N7t9MoiFo2pBPHuFcOsaY5ETYuEyk5gaX7BYP7qT6wKG\n" +
         "BRILmX6DblWqGxG2tKs/AdcHDqQ5QBXrP03uhN68wgo=\n" +
         "\n" +
         "U2FsdGVkX18gtpQSqyH4H5242gZzcZrb0oH7FWw7/MSCxo7h7BVaesZV2N38sr9y\n" +
         "\n" +
         "kVr+wabiNn4RfAB4nNi9gAZHQLok4uxRMALGF2kZk2zpVNPQo6jcdz85fy68gylX\n" +
         "OCQIIdk8JPIwxzHfVvRZqNHDRFDZRlNHUMYScjRPU+DB8avghYAVKMJhLgA/2Tdp\n" +
         "a59uBMBg/yB1yqA5FivxPzOhq92Y4nZuP1R9/yGE9O8K\n" +
         "-----END MESSAGE-----\n";
      String[] lines = message.split( "\n" );
      int i = 1;
      String sessionKey = "";
      String line = lines[i];
      while( i < lines.length && line.length() > 0 ) {
         sessionKey += line;
         line = lines[++i];
      }
      String encryptedMessage = "";
      line = lines[++i];
      while( i < lines.length && line.length() > 0 ) {
         encryptedMessage += line;
         line = lines[++i];
      }
      String digitalSignature = "";
      line = lines[++i];
      while( i < lines.length && ! line.equals( "-----END MESSAGE-----" )) {
         digitalSignature += line;
         line = lines[++i];
      }
      System.out.println( "sessionKey      : " + sessionKey );
      System.out.println( "encryptedMessage: " + encryptedMessage );
      System.out.println( "digitalSignature: " + digitalSignature );
   }
}

实际上,在各个部分中嵌入了新行。划定它们的是一行一行的两行换行。我想你想把断线的每一部分都去掉。我建议采用暴力手段:

StringBuilder sb = new StringBuilder();
String[] parts = input.split("\\r?\\n\\r?\\n"); // should be 3 long
// strip out header and newlines from session key
String[] lines = parts[0].split("\\r?\\n");
for (int i = 1; i < lines.length; ++i) { // skip first line
    sb.append(lines[i]);
}
parts[0] = sb.toString();
// strip out header and newlines from message
sb.setLength(0);
lines = parts[1].split("\\r?\\n");
for (int i = 0; i < lines.length; ++i) {
    sb.append(lines[i]);
}
parts[1] = sb.toString();
// finally, deal with the signature
sb.setLength(0);
lines = parts[2].split("\\r?\\n");
for (int i = 0; i < lines.length - 1; ++i) {
    sb.append(lines[i]);
}
parts[2] = sb.toString();
StringBuilder sb=新建StringBuilder();
String[]parts=input.split(“\\r?\\n\\r?\\n”);//应该是3长
//从会话密钥中去掉标题和换行符
字符串[]行=部分[0]。拆分(\\r?\\n”);
对于(int i=1;i
不优雅,但它清楚地说明了发生了什么


另一种方法是使用
扫描仪
读取每一行并决定如何处理。三行—表头、拖车和空行—将进行特殊处理并影响处理。否则,只需在读取时将每一行附加到
StringBuffer

我也做了类似的操作。问题是,您是否希望这三条数据同时匹配?有3个捕获组?还是三场比赛?苏亚梅尔,我要三场比赛。Jaynathan,我尝试使用“\n”作为delimeter,但它不起作用,因为每行后面都有一个换行符。例如,加密的会话密钥有3行长,每行后跟一个换行符。我甚至尝试使用“\n\n”作为测力计,但也失败了。我同意。如果你只是处理一个证书,有三行。只需将begin/end消息替换为nothing,然后将字符串或正则表达式拆分为\s+(我不相信每个字符串中都有空格,只是在字符串之间。新行不能总是依赖于\r\n\s+是完美的,因为断言每个部分本身没有空格。@ SuMeRe-每个部分都有新行。区分哪些部分是空白行。我希望有一种方法可以用正则表达式解决这个问题,但是你的方法肯定很有效。谢谢你!@Andy-也许有一种方法可以用正则表达式,但我太懒了,没有办法解决它。:)给OP和Ted的一个说明。在正则表达式中,获得换行符的最佳方法是[\r\n]+这意味着以任何顺序换行或回车的任意数字组合一次或多次。它比\r?\n\r?\n或“经典”要干净得多(\r*\n\r*\n*\r\n*)+。但更干净的是\s+,尤其是在每个字符串中没有空格,只有空格的情况下。@Suamere-这是很好的观点。但是,对于我的代码,第一次拆分只能在两个连续的换行符上进行。单换行符不能匹配;但是,
[\r\n]+
(或
\s+
)将匹配一个换行符。将其设置为
[\r\n]{2}
(或
\s\s
)将无济于事,因为
\r\n
将匹配,而您无法将其设置为
[\r\n]{4}
(或
\s{4}
),因为行终止符中可能缺少
\r
\n
(取决于服务器)。对于第二次拆分,
\s+
是完美的。出于惯性,我使用了
\r?\n
。您的所有陈述都是正确的。我只有我的思维模式,因为据我所知,格式化查看时只有一行分隔符。在解析实际证书时,如果不计算开始行和结束行,所有分隔符都是空白这是一段数据。但我认为你的答案更符合OP给出的示例,因此我不能在这里与你争论。这将在每一个换行符处分割,包括嵌入文本每个部分的换行符。OP需要首先在空白行上分离(两个连续的换行符序列)。为保证健壮性,它需要适用于所有类型的行终止符序列:
\r\n
(Windows,HTTP标准)、
\r
(Mac)或
\n
(Unix)。不正确。\s+将一个或多个空格合并为一个。这意味着换行符和这些“空”上可能的空格行。因此,如果手动删除了开始和结束,剩下的将是三个区域的集合。\s+将适用于所有类型的终止符序列。唯一的原因\s+可能不起作用是,如果这些信息行中有一行包含空格,根据certs的规则,它永远不会起作用。但是,如果也不会有空格如果“空”行中有空格,[\r\n]+也可以,但是\s
sessionKey      : SNyeWtz8QD8AKdioMG11wu7U6gG2wD9tekvVrx6VYW+6oJj4Wl8NE+7i5MHbu4Au+vN1Z886lOWka7ekgPF8N7t9MoiFo2pBPHuFcOsaY5ETYuEyk5gaX7BYP7qT6wKGBRILmX6DblWqGxG2tKs/AdcHDqQ5QBXrP03uhN68wgo=
encryptedMessage: U2FsdGVkX18gtpQSqyH4H5242gZzcZrb0oH7FWw7/MSCxo7h7BVaesZV2N38sr9y
digitalSignature: kVr+wabiNn4RfAB4nNi9gAZHQLok4uxRMALGF2kZk2zpVNPQo6jcdz85fy68gylXOCQIIdk8JPIwxzHfVvRZqNHDRFDZRlNHUMYScjRPU+DB8avghYAVKMJhLgA/2Tdpa59uBMBg/yB1yqA5FivxPzOhq92Y4nZuP1R9/yGE9O8K
StringBuilder sb = new StringBuilder();
String[] parts = input.split("\\r?\\n\\r?\\n"); // should be 3 long
// strip out header and newlines from session key
String[] lines = parts[0].split("\\r?\\n");
for (int i = 1; i < lines.length; ++i) { // skip first line
    sb.append(lines[i]);
}
parts[0] = sb.toString();
// strip out header and newlines from message
sb.setLength(0);
lines = parts[1].split("\\r?\\n");
for (int i = 0; i < lines.length; ++i) {
    sb.append(lines[i]);
}
parts[1] = sb.toString();
// finally, deal with the signature
sb.setLength(0);
lines = parts[2].split("\\r?\\n");
for (int i = 0; i < lines.length - 1; ++i) {
    sb.append(lines[i]);
}
parts[2] = sb.toString();