解析变量 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#的主要内容,如果未能解决你的问题,请参考以下文章

获取当前的 URL/URI 没有一些 $_GET 变量

Grafana 无法解析变量

Javascript URI 解析介绍

使用 JSP,taglib URI 是不是意味着我的站点依赖于 URI 解析?

在一个步骤中解析URI对象,并从中获取响应

在 RESTful API 中解析 URI 参数