2010-11-30 4 views
1

정규식을 사용하여 HTML/XML을 구문 분석하거나 조작하는 것은 좋지 않은 생각이며 일반적으로 사용하지 않을 것입니다. 그러나 대안이 없어서 그것을 고려하십시오.Regex 또는 XmlParser를 사용하여 태그에 포함되지 않은 텍스트 바꾸기

C#을 사용하여 태그의 일부가 아닌 문자열 (이상적인 경우 특정 ID가있는 범위 태그) 안의 텍스트를 바꿔야합니다.

예를 들어, 내가 정규식을 사용하여 시도

ABC at start of line or ABC here must be replaced but, <span id="__publishingReusableFragment" >ABC inside span must not be replaced with anything. Another ABC here </span> this ABC must also be replaced

대체 텍스트 (내 경우에는 다른 기간)이있는 범위 내에서 가능하지 않는 다음 텍스트에서 ABC의 모든 instaces을 대체하고 싶은 말은하자 앞을 내다 본다.

string regexPattern = "(?<!id=\"__publishingReusableFragment\").*?" + stringToMatch + ".*?(?!span)"; 

의 라인을 따라 다양한 조합이 있지만 그것에 대해 포기합니다.

XElement로로드하여 거기에서 작성자를 만들고 노드 내부에 텍스트를 가져 오려고했습니다. 그러나 그것도 이해할 수 없었다.

XElement xel = XElement.Parse("<payload>" + inputString + @"</payload>"); 
XmlWriter requiredWriter = xel.CreateWriter(); 

필자는 어떻게 든 노드의 일부가 아닌 문자열을 가져 와서 바꾸기를 원합니다.

기본적으로이 문제를 해결하기위한 제안/해결책을 제공합니다.

도움을 미리 감사드립니다. 여전히

답변

1
resultString = Regex.Replace(subjectString, 
    @"(?<!    # assert that we can't match the following 
         # before the current position: 
         # An opening span tag with specified id 
    <\s*span\s*id=""__publishingReusableFragment""\s*> 
    (?:    # if it is not followed by... 
     (?!<\s*/\s*span) # a closing span tag 
     .     # at any position between the opening tag 
    )*     # and our text 
    )     # End of lookbehind assertion 
    ABC     # Match ABC", 
    "XYZ", RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace); 

구문 분석 HTML에 대한 모든주의와 함께 작동합니다 작동합니다 (당신이 아는 것 같은데 것을, 그래서 내가 여기를 반복하지 않을 것이다) 유효한.

정규식은 앞에 <span id=__publishingReusableFragment"> 태그가없고 앞뒤에 <span> 태그가없는 경우 ABC과 일치합니다. <span> 태그가 중첩 될 수 있으면 분명히 실패합니다.

+0

좋아 보인다. 그러나 span 태그에 몇 가지 추가 속성이있는 경우는 무엇입니까? 예를 들면 다음과 같습니다. ... ... 이제는 span 태그의 끝 뒤에 일치하지 않습니다. ... this ABC ... – Chaitanya

+0

시작하고 있습니다. regexes로 HTML을 파싱하는 것이 좋은 생각이 아닌 모든 이유에 부딪 히게됩니다. 속성에'> '이 포함되지 않으면'<\s*span[^>] * id = ""__ publishingReusableFragment ""[^>] *>'을 사용하여 최상의 결과를 얻을 수 있습니다. –

+0

네, 고마워요. 그래, 그래서 LinqToXML 또는 좋은 LinqToHtml lib와 그것을 걷고 희망이 될 수도 있습니다. 이것은 수동 도구 처리를 줄이기 위해 일부 데이터를 처리해야하는 가져 오기 도구에서 하나 떨어져 버리는 것입니다. – Chaitanya

1

나는 그것의 약간 못생긴 알고 있지만이

var s = 
    @"ABC at start of line or ABC here must be replaced but, <span id=""__publishingReusableFragment"" >ABC inside span must not be replaced with anything. Another ABC here </span> this ABC must also be replaced"; 
var newS = string.Join("</span>",s.Split(new[] {"</span>"}, StringSplitOptions.None) 
    .Select(t => 
     { 
      var bits = t.Split(new[] {"<span"}, StringSplitOptions.None); 
      bits[0] = bits[0].Replace("ABC","DEF"); 
      return string.Join("<span", bits); 
     })); 
+0

전혀 못 생깁니다. 이것은해야 할 일을 수행하는 좋은 방법입니다 (약간 추한 것입니다). 유일한 문제는 모든 범위를 무시한다는 것입니다. 정규 표현식과 같은 특정 ID로 확장되지 않습니다. 이것은 아마 나에게 어울리기 위해 확장되었을 수 있었고, 많은 다른 상황에서 도움이 될 수 있었다. – Chaitanya

관련 문제