我有一个包含以下内容的HTML:
... some text ...
<a href="file.aspx?userId=123§ion=2">link</a> ... some text ...
... some text ...
<a href="file.aspx?section=5&user=678">link</a> ... some text ...
... some text ...
我想解析它并与命名组匹配:
匹配1
组[ “用户”] = 123
基[ “部分”] = 2
匹配2
组[ “用户”] = 678
基[ “部分”] = 5
如果参数总是按顺序排列,我可以这样做,首先是User,然后是Section,但如果订单不同,我不知道该怎么做。
谢谢!
答案 0 :(得分:8)
在我的情况下,我必须解析一个Url,因为WP7中没有实用程序HttpUtility.ParseQueryString。所以,我创建了一个这样的扩展方法:
public static class UriExtensions
{
private static readonly Regex queryStringRegex;
static UriExtensions()
{
queryStringRegex = new Regex(@"[\?&](?<name>[^&=]+)=(?<value>[^&=]+)");
}
public static IEnumerable<KeyValuePair<string, string>> ParseQueryString(this Uri uri)
{
if (uri == null)
throw new ArgumentException("uri");
var matches = queryStringRegex.Matches(uri.OriginalString);
for (int i = 0; i < matches.Count; i++)
{
var match = matches[i];
yield return new KeyValuePair<string, string>(match.Groups["name"].Value, match.Groups["value"].Value);
}
}
}
然后是使用它的问题,例如
var uri = new Uri(HttpUtility.UrlDecode(@"file.aspx?userId=123§ion=2"),UriKind.RelativeOrAbsolute);
var parameters = uri.ParseQueryString().ToDictionary( kvp => kvp.Key, kvp => kvp.Value);
var userId = parameters["userId"];
var section = parameters["section"];
注意:我正在直接返回IEnumerable而不是字典,因为我假设可能存在重复参数的名称。如果有重复的名称,那么字典将抛出异常。
答案 1 :(得分:5)
为什么要使用正则表达式将其拆分出来?
您可以先提取查询字符串。将结果拆分为&amp;然后通过从<= p>上分割结果来创建地图
答案 2 :(得分:1)
您没有指定您正在使用的语言,但这应该在C#中实现:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace RegexTest
{
class Program
{
static void Main(string[] args)
{
string subjectString = @"... some text ...
<a href=""file.aspx?userId=123§ion=2"">link</a> ... some text ...
... some text ...
<a href=""file.aspx?section=5&user=678"">link</a> ... some text ...
... some text ...";
Regex regexObj =
new Regex(@"<a href=""file.aspx\?(?:(?:userId=(?<user>.+?)§ion=(?<section>.+?)"")|(?:section=(?<section>.+?)&user=(?<user>.+?)""))");
Match matchResults = regexObj.Match(subjectString);
while (matchResults.Success)
{
string user = matchResults.Groups["user"].Value;
string section = matchResults.Groups["section"].Value;
Console.WriteLine(string.Format("User = {0}, Section = {1}", user, section));
matchResults = matchResults.NextMatch();
}
Console.ReadKey();
}
}
}
答案 3 :(得分:0)
使用正则表达式首先找到键值对然后进行拆分......似乎不正确。
我对完整的正则表达式解决方案感兴趣。
任何?
答案 4 :(得分:0)
检查出来
\<a\s+href\s*=\s*["'](?<baseUri>.+?)\?(?:(?<key>.+?)=(?<value>.+?)[&"'])*\s*\>
您可以使用群组[“key”]获得对。捕获[i]&amp;基团[ “值”]。捕获[I]
答案 5 :(得分:0)
也许是这样的事情(我在正则表达式上生锈了,反正他们一开始并不擅长。未经测试):
/href="[^?]*([?&](userId=(?<user>\d+))|section=(?<section>\d+))*"/
(顺便说一下,XHTML格式不正确;&amp;应该是&amp; amp;属性。)
答案 6 :(得分:0)
另一种方法是将捕获组放在预测中:
Regex r = new Regex(@"<a href=""file\.aspx\?" +
@"(?=[^""<>]*?user=(?<user>\w+))" +
@"(?=[^""<>]*?section=(?<section>\w+))";
如果只有两个参数,那么没有理由比Mike和strager提出的基于交替的方法更喜欢这种方式。但是如果你需要匹配三个参数,那么其他正则表达式将增长到当前长度的几倍,而这个只需要另外一个前瞻,就像两个现有的一样。
顺便说一句,与你对Claus的回应相反,你所使用的语言非常重要。从一种语言到下一种语言的功能,语法和API都有很大差异。
答案 7 :(得分:0)
你没有说你正在使用哪种正则表达式。由于您的示例URL链接到.aspx文件,我将假设.NET。在.NET中,单个正则表达式可以具有多个具有相同名称的命名捕获组,而.NET将它们视为一个组。因此,您可以使用正则表达式
userID=(?<user>\d+)§ion=(?<section>\d+)|section=(?<section>\d+)&userID=(?<user>\d+)
这个简单的正则表达式与交替将比任何具有外观的技巧更有效。如果您的要求包括仅在链接中匹配参数,则可以轻松扩展它。
答案 8 :(得分:0)
克服排序问题的简单python实现
In [2]: x = re.compile('(?:(userId|section)=(\d+))+')
In [3]: t = 'href="file.aspx?section=2&userId=123"'
In [4]: x.findall(t)
Out[4]: [('section', '2'), ('userId', '123')]
In [5]: t = 'href="file.aspx?userId=123§ion=2"'
In [6]: x.findall(t)
Out[6]: [('userId', '123'), ('section', '2')]