C# 解析变量URI(正则表达式、URI、字符串函数?)#
我正在编写一个RTSP客户端模块,为此,我需要解析一个非常可变的URI。但我完全被我应该使用哪种方法(大多数故障保护)以及如何实现这一点所困扰 示例URI可能如下所示:C# 解析变量URI(正则表达式、URI、字符串函数?)#,c#,regex,string,parsing,url,C#,Regex,String,Parsing,Url,我正在编写一个RTSP客户端模块,为此,我需要解析一个非常可变的URI。但我完全被我应该使用哪种方法(大多数故障保护)以及如何实现这一点所困扰 示例URI可能如下所示: rtsp://192.168.1.100:554/videocam/media/1/video/1 \_/ \_______________/\_______/\______________/ | | | | scheme authority
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
也许有一个图书馆可以完成这样的任务
谢谢。下面是一个如何使用UriBuilder类的快速示例。这有点冗长,因为这是一个示例,还没有准备好进行生产。如果要标识更多子节点,则可以将它们添加到子列表中,如示例所示
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();
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;
}
}
}
类程序
{
私有静态字符串_scheme=string.Empty;
私有静态字符串_host=string.Empty;
私有静态字符串_sub=string.Empty;
静态void Main(字符串[]参数)
{
解析URI(“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/摄像机”);
//添加新子对象的示例
子条款添加(“样本”);
ParseUri(“192.168.1.100:6000/样本/”;
Console.ReadLine();
}
私有静态void ParseUri(字符串URI)
{
UriBuilder uri=新的UriBuilder(uri);
_scheme=uri.scheme;
_host=uri.host;
_sub=string.Empty;
StringBuilder sb=新的StringBuilder();
foreach(uri.uri.Segments中的字符串s)
{
如果(子项包含(s.替换(“/”,“))
{u sub=s;}
其他的
{sb.Append(s);}
}
Console.Out.WriteLine(“+;
WriteLine(“URI:{0}”,URI);
Console.Out.WriteLine(“Scheme:{0}”,_Scheme);
Console.Out.WriteLine(“sub:{0}”,_-sub);
WriteLine(“mediaControl:{0}”,sb.ToString());
}
私有静态列表子
{
得到
{
List sub=新列表();
子条款添加(“视频摄像机”);
返回子节点;
}
}
}
你能不能把它沿着“/”分开,然后数一数。e、 左边的第二个最后一个必须始终是autority等。那么您的第二个示例没有“sub”,第三个示例没有“mediacontrol”?mediacontrol是否始终是/string/int/对的“列表”?此外,子控件是否可以包含数字,并且mediacontrol必须以字符开头?我很乐意提供帮助,但需要有某种方法来区分“mediacontrol”/“medialevel”和“sub”。。。如果您没有mediacontrol,但是sub是
media/3/video/4
,或者如果有一个类似mediacontrol的sub,比如media/1/video/4/media/3/video/123
?@CodeJockey实际上有一个mediacontrol-它由大多数设备通过SDP字符串返回,但有时以一种非常奇怪的方式:一些设备返回一个完美的使用字符串,例如media/1/video/2/或track1video2,但其他设备返回“m1;v2”或包含子路径的完整绝对路径。所以我认为这不可靠。主机/端口问题解决了,这要感谢URI类的强大功能和L.B的提示(这太微不足道了),但我仍然坚持将路径与mediacontrol分离。另一个摄像头我提出了一个新的案例。。非常令人困惑:rtsp://192.168.1.117:554/stream1_channel1 我认为这显然是一个mediacontrol,但由于摄像头在一个通道上只有一个流,并且在分析SDP字符串后,它是一个子路径(在本例中,mediacontrol是“vidshow1”。)荒谬!我明白,但这些检查似乎构成了这个问题的有趣部分。我相信这是给出简单示例的正确答案。如果有更复杂的异常需要说明,那么也应该说明它们。@Menefee在仔细检查后,您可能会注意到示例中的一个URL的格式为IP:Port/MediaLevel
(无“sub”)。因此,尽管我认为这个问题还有改进的余地,这确实不是一个完全正确的答案
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);