【问题标题】:How to extract the session id from an RTSP message's content?如何从 RTSP 消息的内容中提取会话 ID?
【发布时间】:2017-03-03 21:13:04
【问题描述】:

我有一个这样的字符串:

RTSP/1.0 200 OK
CSeq: 3
Server: Ants Rtsp Server/1.0
Date: 21 Oct 2016 15:55:30 GMT
Session: 980603187; timeout=60
Transport: RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=F006B800

我要提取会话号(980603187)

有人可以帮忙吗?

【问题讨论】:

  • 您是否已经将其转换为字符串,或者您想转换为字符串然后提取会话信息?
  • 检查 javadoc 中的 String 类,尤其是寻找 substringindexOf 方法。
  • 是的,我已经转换成字符串了

标签: java string substring


【解决方案1】:

获得每个标头后,您可以在RFC 2336 中查找指定 RTSP 协议的规范。

首先,你应该把你的字符串分成几行。根据规范,行以 CR/LF 结尾。第一行表示响应,其他应该是头字段。

定义是:

 Session  = "Session" ":" session-id [ ";" "timeout" "=" delta-seconds ]

其中session-id 指定为:

 session-id   =   1*( ALPHA | DIGIT | safe )

这意味着您不应将其与数字混淆。安全的定义是

   safe               =  "\$" | "-" | "_" | "." | "+"

和 alpha 表示所有大写和小写数字。顺便说一句,这意味着可以放入一个 base 64 url​​ 编码的二进制 session-id。

好的,现在它变成了寻找会话ID的问题。您遍历所有行(第一行除外),然后查找匹配的行:

   ^Session[ \t]*:[ \t]*([a-zA-Z0-9\$\-_.+]+).*$

这将仅匹配有效的会话标头/有效的会话标识符。请注意,该标准对空格的含义很模糊,因此我在冒号“:”前后跳过了空格和制表符。然后会话标识符在正则表达式的第 1 组中。

您当然可以在需要时通过在正则表达式中包含超时来轻松扩展它。


请注意,在 Java 中使用正则表达式之前,您必须对反斜杠字符进行双重转义。也可以使用 Pattern 类中定义的 Posix 字符类来使正则表达式更具可读性。

【讨论】:

  • 写这个答案是为了通过开始阅读标准来创建一个处理这个问题的通用方法。
【解决方案2】:

只需将regular expression 与组一起使用,然后将组的值提取为下一个:

String content ="RTSP/1.0 200 OK\n" +
   "CSeq: 3\n" +
   "Server: Ants Rtsp Server/1.0\n" +
   "Date: 21 Oct 2016 15:55:30 GMT\n" +
   "Session: 980603187; timeout=60\n" +
   "Transport: RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=F006B800\n";
Pattern pattern = Pattern.compile("Session: ([a-zA-Z0-9$\\-_.+]+)");
Matcher matcher = pattern.matcher(content);
if (matcher.find()) {
    System.out.println(matcher.group(1));
}

输出:

980603187

说明:

Session: ([a-zA-Z0-9$\\-_.+]+)
  • Session: 与字符 Session: 逐字匹配(区分大小写)
  • ([a-zA-Z0-9$\\-_.+]+):捕获与多个连续 ALPHA、DIGIT 或 SAFE 字符(至少一个)匹配的组(参见 RFC 2326 chapter 3.4 Session Identifiers

【讨论】:

  • 快 12 秒。有关系吗? xD
  • 是的,因为你犯了一个错误;根据 RFC 2326,";" 仅在存在 optional 超时时才存在。
  • 啊好吧!谢谢 !! :)
【解决方案3】:

使用正则表达式!拥有String str = ..,提取所需的数字,正则表达式捕获Session:; 之间的任何内容:

Session: (.+);

请随意指定字母 \\w+ 或数字 \\d+。注意 Java 中的双重转义。第一个匹配的m.group(1) 是您的结果:

Pattern p = Pattern.compile("Session: (.+);");
Matcher m = p.matcher(str);

if (m.find()) {
    System.out.println(m.group(1));
}

输出980603187。查看Regex101的解释。


在某些情况下,; timeout 是可选的,需要修改使用的正则表达式:

Session: (.+?)[\n;]

【讨论】:

  • 错了,超时,因此';'是可选的。
  • 好吧,OP 还没有说这件事。此外,我不熟悉 RFC 2326 标准。但是我可以将它包含在答案中。
  • 嗯,这就是你不阅读标准的结果。我以前也没有使用过它,但同时我查了一下。这就是你获得脆弱代码的方式。
【解决方案4】:

如果您在依赖项中使用 apache-commons,那么您可以在一行内完成:

StringUtils.substringBetween(string, "Session: ", ";");

【讨论】:

    猜你喜欢
    • 2020-09-05
    • 2021-12-13
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    • 2020-12-28
    • 1970-01-01
    相关资源
    最近更新 更多