2008-11-13 13 views
8

아무도 묻기 전에 어떤 종류의 스크린 스크랩을하고 있지 않습니다.Regex - div로 중첩 된 div로 id의 div 내용 찾기

HTML 문자열을 구문 분석하여 특정 ID가있는 div를 찾으려고합니다. 나는이 일을 할 수 없다. 다음 표현식은 한 인스턴스에서 작동했지만 다른 인스턴스에서는 작동하지 않았습니다. 그것이 html에있는 여분 성분으로해야 한 ㄴ다는 것을 있건 없건간에 나는 확실하지 않다.

<div\s*?id=(\""|&quot;|&#34;)content(\""|&quot;|&#34;).*?>\s*?(?>(?! <div\s*?> | </div>) | <div\s*?>(?<DEPTH>) | </div>(?<-DEPTH>) | .?)*(?(DEPTH)(?!))</div> 

관련 사업부를 올바르게 올바른 ID를 가지는 최초의 사업부를 찾는 것입니다,하지만 다음 첫 번째 닫는 DIV에 문을 닫습니다, 그리고.

<div id="firstdiv">begining content<div id="content">some other stuff 
    <div id="otherdiv">other stuff here</div> 
    more stuff 
    </div> 
</div> 

이 다시

<div id="content">some other stuff 
    <div id="otherdiv">other stuff here</div> 
    more stuff 
</div> 

가지고해야하지만, 어떤 이유로, 그것을하지 않습니다. 그것은 돌아오고 있습니다 :

<div id="content">some other stuff 
     <div id="otherdiv">other stuff here</div> 

아무도 쉽게 처리 할 수 ​​있습니까?

분명히하기 위해 이것은 .NET에 있으며 DEPTH 키워드를 사용하고 있습니다. 자세한 내용은 here을 참조하십시오.

+0

upvoted - 이것은 정규식이 수행 할 수있는 한계를 새로운 프로그래머에게 가르쳐주는 훌륭한 질문입니다. – Cybis

+0

아마도 순수한 Reg. 특급. 그러나 확실히 .net으로 할 수 있습니다. 내 대답을 보라. – pro3carp3

답변

5

.NET에서이 작업을 수행 할 수 있습니다

(?<text> 
(<div\s*?id=(\"|&quot;|&\#34;)content(\"|&quot;|&\#34;).*?>) 

    (?> 
     .*?</div> 
    | 
     .*?<div (?>depth) 
    | 
     .*?</div> (?>-depth) 
)*) 
    (?(depth)(?!)) 
.*?</div> 

당신은 만일 Singleline 옵션을 사용해야합니다. 다음은 콘솔을 사용한 예입니다.

using System; 
using System.Text.RegularExpressions; 

namespace Temp 
{ 
    class Program 
    { 
     static void Main() 
     { 
      string s = @" 
<div id=""firstdiv"">begining content<div id=""content"">some other stuff 
    <div id=""otherdiv"">other stuff here</div> 
    more stuff 
    </div> 
</div>"; 
      Regex r = new Regex(@"(?<text>(<div\s*?id=(\""|&quot;|&\#34;)" 
       + @"content(\""|&quot;|&\#34;).*?>)(?>.*?</div>|.*?<div " 
       + @"(?>depth)|.*?</div> (?>-depth))*)(?(depth)(?!)).*?</div>", 
       RegexOptions.Singleline); 
      Console.WriteLine("HTML:\n"); 
      Console.WriteLine(s); 
      Match m = r.Match(s); 
      if (m.Success) 
      { 
       Console.WriteLine("\nCaptured text:\n"); 
       Console.WriteLine(m.Groups[4]); 

      } 
      Console.ReadLine(); 
     } 
    } 
} 
+0

정규 언어의 정의를 변경하려면 Microsoft에 맡기십시오. – Cybis

5

DIV 태그 안에 중첩 된 DIV 태그의 수를 추적 할 수있는 정규식을 요청 하시겠습니까? 나는 정규식으로는 불가능하다고 생각합니다.

정규 표현식을 사용하여 첫 번째 DIV 태그의 색인을 가져온 다음 해당 문자열에서 문자를 반복하고 그 색인에서 시작하여 열려있는 div 태그의 수를 유지할 수 있습니다. 가까운 div 태그를 만나고 개수가 0이면 원하는 하위 문자열을 포함하는 문자열에 시작 및 끝 색인이 생깁니다.

+0

나는 이것을 허용하는 재귀 확장이 있지만 순수 정규식에서는 수행 할 수 없다는 것을 알고 있습니다. –

0

어떤 프로그래밍 언어를 사용합니까? 그것이 닷넷이고 html이 잘 형성 되었다면 XmlDocument 또는 XDocument 객체에로드 할 수 있고 xpath 쿼리를 수행 할 수 있습니다.

+0

... 아마 정규식보다 빠를 것입니다. –

2

사이비 스는 진실을 말합니다. 이런 종류의 것들은 Context-Free Language에 속하며, 정규 언어 (정규 표현식에 의해 다루어지는 것들)보다 강력합니다. 컴퓨터 과학 이론이 많이 포함되어 있지만, 소금을 가치있게 생각하는 언어는 아마도 여러분이 사용해야하는 이런 종류의 내용을 담은 라이브러리를 갖출 것이라고 말할 수 있습니다.