Замените текст, не содержащийся в теге, используя Regex или XmlParser. - PullRequest
1 голос
/ 30 ноября 2010

Я знаю, что использование регулярных выражений для разбора или манипулирования HTML / XML - плохая идея, и я обычно никогда бы этого не сделал.Но учитывая это из-за отсутствия альтернатив.

Мне нужно заменить текст внутри строки, которая еще не является частью тега (в идеале тег span с определенным идентификатором), используя C #.

ДляНапример, допустим, я хочу заменить в следующем тексте все элементы ABC, которые не находятся внутри промежутка, на альтернативный текст (еще один промежуток в моем случае)

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

Я пытался использоватьрегулярное выражение с обоими смотреть вперед и смотреть за утверждением.Различные комбинации по линиям

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

, но отказались от этого.

Я пытался загрузить его в XElement и попытаться создать оттуда писателя и получить текст не внутри узла,Но и этого не смог понять.

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

Я надеюсь как-нибудь использовать писатель, чтобы получить строки, которые не являются частью узла, и заменить их.

По сути, яоткрыт для любых предложений / решений для решения этой проблемы.

Заранее спасибо за помощь.

Ответы [ 2 ]

2 голосов
/ 30 ноября 2010
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 (которые, кажется, вы знаете, поэтому я не буду повторять их здесь), все еще в силе.

Регулярное выражение соответствует ABC, если ему не предшествуетоткрывающим тегом <span id=__publishingReusableFragment"> и, если между ними нет закрывающего тега <span>.Очевидно, что он потерпит неудачу, если будут вложенные теги <span>.

2 голосов
/ 30 ноября 2010

Я знаю, это немного некрасиво, но это будет работать

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);
        }));
...