【问题标题】:Regex for finding value inside parenthesis用于在括号内查找值的正则表达式
【发布时间】:2014-02-18 08:13:46
【问题描述】:

我有一行代码:

<link href="<%= Page.ResolveClientUrl("~/Styles/CAR.css") %>" rel="stylesheet" type="text/css" />

我只想从中提取~/Styles/CAR.css。 请让我知道正则表达式。 链接 href 标记也可能包含其他语法来引用 css。 例如,&lt;link href="&lt;%= Url.Content("~/Styles/CAR.css") %&gt;" rel="stylesheet" type="text/css" /&gt;

【问题讨论】:

  • 我有一行代码:" rel="stylesheet" type="text/ css" /> 我只想从中提取“~/Styles/CAR.css”。请让我知道正则表达式。链接 href 标记也可能包含其他语法来引用 css。例如," rel="stylesheet" type="text/css" />
  • 我的印象是,当您尝试使用正则表达式解析 html 时会发生不好的事情...stackoverflow.com/a/1732454/24908 =)
  • Page.ResolveClientUrlUrl.Content 不一定会产生相同的输出,那么这如何可靠呢?为什么不解析生成的 HTML 而不是服务器端代码?

标签: c# .net regex


【解决方案1】:

我建议您使用HtmlAgilityPack(可从 NuGet 获得)进行 HTML 解析。获取href 属性值将如下所示:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(stringWithHtml);
var link = doc.DocumentNode.SelectSingleNode("//link[@href]");
var href = link.Attributes["href"].Value;

然后你可以从属性的内容中提取~/Styles/CAR.css。正则表达式在这里很好,但你也可以避免它:

int startIndex = href.IndexOf('"');
int endIndex = href.LastIndexOf('"');
var result = href.Substring(startIndex + 1, endIndex - startIndex - 1);
// ~/Styles/CAR.css

使用正则表达式提取路径如下所示

var match = Regex.Match(href, @"ResolveClientUrl\(""(.*)""\)");
if (match.Success)
    result = match.Groups[1].Value;

【讨论】:

    【解决方案2】:

    除了你should'nt parse HTML with regex,我会去的

    \(\"(.+)\"\)
    

    作为您的正则表达式。只需提取 ("") 之间的任何内容。

    例如:

    string strRegex = @"\(\""(.+)\""\)";
    Regex myRegex = new Regex(strRegex, RegexOptions.None);
    string strTargetString = @"<link href=""<%= Page.ResolveClientUrl(""~/Styles/CAR.css"") %>"" rel=""stylesheet"" type=""text/css"" />";
    
    foreach (Match myMatch in myRegex.Matches(strTargetString))
    {
      if (myMatch.Success)
      {
        // Add your code here
      }
    }
    

    (示例代码取自http://regexhero.net/tester/

    如果&lt;link href=""&lt;%= Page.ResolveClientUrl(""~/Styles/CAR.css"") %&gt;"" rel=""stylesheet"" type=""text/css"" /&gt;只会出现一次,或者您只想获得第一次出现,那么您可以摆脱for循环并使用:

    string strRegex = @"\(\""(.+)\""\)";
    Regex myRegex = new Regex(strRegex, RegexOptions.None);
    string strTargetString = @"<link href=""<%= Page.ResolveClientUrl(""~/Styles/CAR.css"") %>"" rel=""stylesheet"" type=""text/css"" />";
    
    Match myMatch = myRegex.Match(strTargetString);
    

    这里的区别在于使用Regex.Matches(string)(返回一个MatchCollection;每个匹配的出现)与Regex.Match(string)(返回一个Match;仅第一个匹配的出现)。

    【讨论】:

    • 我不想在这里使用 foreach 循环。有什么东西,我可以直接将“myRegex.Matches(strTargetString))”值分配给“myMatch”。当我使用“Match myMatch = myRegex.Matches(strTargetString);”时,我在 myMatch 中得到空值。
    • @Kanaiya 以及​​ Matches(string) 返回一个 MatchCollection,所以每场比赛。如果您只想要一个匹配项,请使用Match(string),这将返回第一次出现(如果有)。如果&lt;link href=... 只出现一次,那么您可以使用Match myMatch = myRegex.Match(strTargetString) 并且没有for 循环。
    • 非常感谢。这行得通,但我得到 {("~/Styles/CAR.css")}。我只需要 ~/Styles/CAR.css 即可提取。我尝试编辑您的正则表达式,但仍然无法获得理想的输出。请让我知道正则表达式以获得输出值。
    • @Kanaiya 很可能这不是正则表达式的问题。 整个匹配("~/Styles/CAR.css"),因为我们在("")上也匹配!您只想提取第一个capturing group 而已!这可以通过myMatch.Groups[1].Value 完成(但要小心:当正则表达式不匹配时,Groups-property 不会有两个(或更多)成员!)
    【解决方案3】:

    使用这个:

    /\(([^\)]*)\)/
    

    用 perl 测试:

    > cat temp
    <link href="<%= Page.ResolveClientUrl("~/Styles/CAR.css") %>" rel="stylesheet" type="text/css" />
    > perl -lne 'print $1 if(/\(([^\)]*)\)/)' temp
    "~/Styles/CAR.css"
    > 
    

    【讨论】:

      【解决方案4】:

      " rel="stylesheet" type="text/css" />

      对于快速正则表达式,我们可以使用括号内的引号内的信息 (("~/Styles/CAR.css") ) 并使用该信息将其归为一组。

      转义括号一个快速的正则表达式将是

      "(.*/>)

      在上面的正则表达式中有两组。第一个匹配组会给我们所需的信息,即 ~/Styles/CAR.css。

      您可以在http://regexpal.com/ 中查看并尝试其他模式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多