2009-11-17 68 views
1

我不知道我在做什麼錯。我正在嘗試使用asp.net regex.replace,但它不斷更換錯誤的項目。我在做什麼錯誤與我的正則表達式?

我有2個替換。第一個是我想要的,它取代了我想要的。下一個幾乎是鏡像的替換並不能取代我想要的。

所以這是我的示例代碼

<%@ Page Title="Tour" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> 
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server"> 
    <title>Website Portfolio Section - VisionWebCS</title> 
    <meta name="description" content="A" /> 
    <meta name="keywords" content="B" /> 
</asp:Content> 
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 
    <!-- **START** --> 

我期待更換兩個meta標籤。

<meta name=\"description\" content=\"A\" /> 
<meta name=\"keywords\" content=\"B\" /> 

在我的代碼首先我更換關鍵字meta標籤與

<meta name=\"keywords\" content=\"C\" /> 

這個工作,所以我的下一個任務是與此

<meta name=\"description\" content=\"D\" /> 

這不更換描述meta標籤而是替代「關鍵字」元標記,然後替換「描述」標記。

這是我的測試程序,所以你們都可以嘗試一下。只需通過它在C#控制檯應用程序。

private const string META_DESCRIPTION_REGEX = "<\\s* meta \\s* name=\"description\" \\s* content=\"(?<Description>.*)\" \\s* />"; 
     private const string META_KEYWORDS_REGEX = "<\\s* meta \\s* name=\"keywords\" \\s* content=\"(?<Keywords>.*)\" \\s* />"; 
     private static RegexOptions regexOptions = RegexOptions.IgnoreCase 
            | RegexOptions.Multiline 
            | RegexOptions.CultureInvariant 
            | RegexOptions.IgnorePatternWhitespace 
            | RegexOptions.Compiled; 

     static void Main(string[] args) 
     { 

      string text = "<%@ Page Title=\"Tour\" Language=\"C#\" MasterPageFile=\"~/Views/Shared/Site.Master\" Inherits=\"System.Web.Mvc.ViewPage\" %><asp:Content ID=\"Content1\" ContentPlaceHolderID=\"HeadContent\" runat=\"server\"> <title>Website Portfolio Section - VisionWebCS</title> <meta name=\"description\" content=\"A\" /> <meta name=\"keywords\" content=\"B\" /></asp:Content><asp:Content ID=\"Content2\" ContentPlaceHolderID=\"MainContent\" runat=\"server\"><!-- **START** -->"; 
      Regex regex = new Regex(META_KEYWORDS_REGEX, regexOptions); 
      string newKeywords = String.Format("<meta name=\"keywords\" content=\"{0}\" />", "C"); 
      string output = regex.Replace(text, newKeywords); 

      Regex regex2 = new Regex(META_DESCRIPTION_REGEX, regexOptions); 
      string newDescription = String.Format("<meta name=\"description\" content=\"{0}\" />", "D"); 
      string newOutput = regex2.Replace(output, newDescription); 
      Console.WriteLine(newOutput); 
     } 

這讓我的

<%@ Page Title="Tour" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage" %> 
<asp:Content ID="Content1" ContentPlaceHold erID="HeadContent" runat="server"> 
    <title>Website Portfolio Section - VisionW 
     ebCS</title> 
    <meta name="description" content="D" /> 
</asp:Content> 
<asp:Conten t ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 
    <!-- **START** 
    --> 

感謝

回答

6

要回答你的問題沒有無用的生活經驗教訓,你有麻煩,因爲貪婪的量詞。通過添加問號儘量使他們懶惰:

<meta\\s+?name=\"description\"\\s+?content=\"(?<Description>.*?)\"\\s*?/> 

當然這個表達式將不會爲世界上所有的網頁工作,但如果你只需要進行一些快速更換腳本自己的模板,正則表達式是最快最簡單的解決方案和路要走。

+0

嗯,這有效,但我不明白。我認爲即使我正在使用一個貪婪的量詞,它會一直持續到它看到「/>」並停止。那麼爲什麼它會更進一步呢?即使在檢查這個被捕獲的表達式時,它總是會返回一個。 – chobo2 2009-11-17 16:46:25

7

你在做什麼錯的最終輸出?你是parsing HTML with a regex

爲.NET庫推薦:HTML Agility Pack

+0

所以 - 你會做什麼,而不是呢? – 2009-11-17 06:44:07

+1

@ will:+1但你應該提供一個鏈接/代碼snipet如何解析它與一個適當的解析器 – RageZ 2009-11-17 06:44:23

+0

單獨的圖形是有趣的足以點擊 – bobby 2009-11-17 06:44:23

0

瞭解,熱愛,並使用DOM。它是W3C(HTML標準體)批准的解析XML(HTML是XML的子集)文檔的方式。除非你有足夠的理由相信你的輸入HTML是非常錯誤的,否則這通常是最好的開始。

Learn here

你是高度鼓勵退房 Walkthrough: Accessing the DHTML DOM from C#

您也可以嘗試jQuery的,因爲它可以很容易搜索DOM。 Like so

1

我同意@ serg555的回答 - 問題是與貪婪的量詞 - 讓他們懶惰'?「要解決這個問題

<meta\\s*name=\"description\"\\s*content=\"(?<Description>.*?)\"\\s*/> 
0

我需要的URL的說明在C#代碼,並使用this site檢查我的正則表達式的代碼。

這是我最後的這工作知府:

 WebClient x = new WebClient { Encoding = Encoding.UTF8 }; 
      string source = x.DownloadString(url); 

      string description = Regex.Match(source, "<meta[^>]*name=[\"|\']description[\"|\'][^>]*content=[\"]([^\"]*)[\"][^>]*>", RegexOptions.IgnoreCase).Groups[1].Value; 
相關問題