解析变量 URI (RegEx, Uri, String-Functions?) c#
Posted
技术标签:
【中文标题】解析变量 URI (RegEx, Uri, String-Functions?) c#【英文标题】:Parse variable URI (RegEx, Uri, String-Functions?) c# 【发布时间】:2012-08-15 17:48:14 【问题描述】:我正在编写一个 RTSP 客户端模块,为此,我需要解析一个非常可变的 URI。但我完全不知道应该使用哪种方法(最安全)以及如何实现这一点。
示例 URI 可能如下所示:
rtsp://192.168.1.100:554/videocam/media/1/video/1
\_/ \_______________/\_______/\______________/
| | | |
scheme authority [sub] [mediacontrol]
还有其他可能性:
192.168.1.100/videocam/media/1/video/1
192.168.1.100:6000/media/1/video/1
192.168.1.100:6000/videocam
我需要以下信息:
IP | how can I recognise this pattern [num].[num].[num].[num]?
Port | easy if the string contains rtsp://, but what about just a number? 1-65555
Sub | Optional subpath, can completely vary!
MediaLevel | Optional MediaLevel (indicator for stream/track),
not to be confused with the path. MediaLevel can be also just like this: track1 or m1s3 or media1/video1.. see?
I can't go for the slash, also the path also can contain multiple slashes
也许有用于此类任务的库?
谢谢。
【问题讨论】:
你不能把它沿着 '/' 划分然后 count 。例如,左边的倒数第二个必须始终是 autority 等..? 所以你的第二个例子没有“sub”,第三个没有“mediacontrol”? mediacontrol 总是 /string/int/ 对的“列表”吗?另外,sub 是否可以包含数字,并且 mediacontrol 必须以字符开头? 我很乐意提供帮助,但需要一些方法来区分“媒体控制”/“媒体级别”和“子”...如果您没有媒体控制,但子是media/3/video/4
或者如果有一个类似的子with 一个媒体控件,比如media/1/video/4/media/3/video/123
???
@CodeJockey 实际上有一个 mediacontrol - 大多数设备通过 SDP 字符串返回它,但有时以一种非常奇怪的方式返回:某些设备返回一个完美的使用字符串,例如 media/1/video/ 2/ 或 track1video2,但其他返回诸如“m1;v2”之类的东西或完整的绝对路径,包括。子路径。所以我认为这不可靠。主机/端口解决了,这要归功于 URI 类的英雄功能和 L.B 的提示(这真是微不足道..),但我仍然坚持将路径与媒体控制分开。另一台相机我提出了一个新案例,这很令人困惑:
rtsp://192.168.1.117:554/stream1_channel1 我认为这显然是一个媒体控制,但由于相机在 1 个通道上只有 1 个流并且在分析 SDP 字符串后,它是子路径(在这种情况下,媒体控件 - 没有记录在案的是“vidshow1”..)荒谬!
【参考方案1】:
var uri = new Uri("rtsp://192.168.1.100:554/videocam/media/1/video/1");
var host = uri.Host;
var port = uri.Port;
var sub = uri.Segments[1];
var mlevel = uri.Segments.Skip(2).ToArray();
【讨论】:
我明白,但这些检查似乎构成了这个问题的有趣部分。 我相信这是给出的简单示例的正确答案。如果有更复杂的例外需要考虑,也应该提出。 @Menefee 在严格检查时,您可能会注意到示例中的其中一个 URL 的格式为IP:Port/MediaLevel
(没有“子”),所以虽然我想说的是问题,这真的不是一个完全正确答案【参考方案2】:
这里是一个如何使用 UriBuilder 类的简单示例。它有点冗长,因为它是一个示例,还没有准备好投入生产。如果要识别更多的子,则可以将它们添加到子列表中,如示例所示。
class Program
private static string _scheme = string.Empty;
private static string _host = string.Empty;
private static string _sub = string.Empty;
static void Main(string[] args)
ParseUri("rtsp://192.168.1.100:554/videocam/media/1/video/1");
ParseUri("192.168.1.100/videocam/media/1/video/1");
ParseUri("192.168.1.100:6000/media/1/video/1");
ParseUri("192.168.1.100:6000/videocam");
// example of adding a new sub
Sub.Add("sample");
ParseUri("192.168.1.100:6000/sample/");
Console.ReadLine();
private static void ParseUri(string URI)
UriBuilder uri = new UriBuilder(URI);
_scheme = uri.Scheme;
_host = uri.Host;
_sub = string.Empty;
StringBuilder sb = new StringBuilder();
foreach (string s in uri.Uri.Segments)
if (Sub.Contains(s.Replace("/","")))
_sub = s;
else
sb.Append(s);
Console.Out.WriteLine("+++++++++++++");
Console.Out.WriteLine("URI: 0",URI);
Console.Out.WriteLine("Scheme: 0", _scheme);
Console.Out.WriteLine("sub: 0",_sub);
Console.Out.WriteLine("mediaControl: 0", sb.ToString());
private static List<string> Sub
get
List<string> sub = new List<string>();
sub.Add("videocam");
return sub;
【讨论】:
【参考方案3】: trace("Url : 0", turl.Text);
var uri = new Uri(turl.Text);
string host = uri.Host;
int port = uri.Port;
string userInfo = uri.UserInfo;
string subStream = "";
string userName = "";
string password = "";
if (uri.Segments?.Any() == true)
subStream = string.Join("", uri.Segments);
if (!string.IsNullOrEmpty(userInfo))
if (userInfo.Contains(":"))
string[] data = userInfo.Split(':');
userName = data[0];
password = data[1];
else
userName = userInfo;
trace("host : 0", host);
trace("port : 0", port);
trace("userName : 0", userName);
trace("password : 0", password);
trace("subStream: 0", subStream);
【讨论】:
以上是关于解析变量 URI (RegEx, Uri, String-Functions?) c#的主要内容,如果未能解决你的问题,请参考以下文章