2010-09-12 2 views
0

У меня есть следующий код, чтобы сначала удалить HTML-тег, а затем выделить искомый термин в пределах полученного текста:asp.net regex.replace()

protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e) 
{ 
    try 
    { 
     // get search value query string 
     string searchText = Request.QueryString["search"].Trim(); 
     string encodedValue = Server.HtmlEncode(searchText); 

     Literal Content = e.Item.FindControl("Content") as Literal; 
     string contentText = Content.Text; 
     Content.Text = Regex.Replace(contentText, @"<(.|\n)*?>", string.Empty).Replace(encodedValue, "<font class='highlight2'>" + encodedValue + "</font>"); 
    } 
    catch 
    { 
     // do nothing 
    } 
} 

Это работает до некоторой степени, но вторая замена не без учета регистра. Как я могу сделать вторую замену также с помощью regex.replace(), поэтому чувствительность к регистру не является проблемой? Спасибо!

ответ

2

Используйте this overload который принимает RegexOptions. Вам нужно значение IgnoreCase.

+0

Это будет 'String.Replace', который не имеет этой перегрузки. – Kobi

+0

@Kobi, Если это необходимо для учета нечувствительности к регистру, он должен использовать Regex.Replace. В [docs] (http://msdn.microsoft.com/en-us/library/fk49wtc1.aspx) * Этот метод выполняет поиск по порядку (с учетом регистра и без учета культуры), чтобы найти oldValue. * –

+0

Да , но то, что Скотт вызывает *, - это String.Replace. Он вызывает Replace на значение, возвращаемое Regex.Replace, которое является строкой. –

2

Сначала давайте поговорим о регулярном выражении, которое вы используете для удаления тегов, <(.|\n)*?>. Если вы хотите, чтобы точка соответствовала чему-либо , включая a newline, вы должны использовать режим Singleline. Он также известен как режим DOTALL в некоторых вариантах, потому что это то, что он делает: позволяет точка соответствовать символам новой строки. Вы можете использовать флаг RegexOptions.Singleline для этого, или встроить его в регулярном выражении с инлайн модификатором:

`(?s)<.*?>` 

Это все еще довольно хрупкое, но я оставлю это при том, что, потому что нет никакого способа, чтобы сделать это пуленепробиваемый; регулярные выражения и HTML в корне несовместимы.

Что касается второй замены, первое, что вам нужно сделать, это разбить эти вызовы с цепными вызовами - на самом деле я бы сказал, что они никогда не должны были быть прикованы. Подача результата Regex.Replace прямо на String.Replace является либо ошибкой, либо чрезмерно умной. В любом случае у вас есть, чтобы разделить их, если вы хотите позвонить в Regex.Replace дважды.

Вам также необходимо избегать любых метасимволов регулярного выражения в выражении поиска, предполагая, что вы все еще хотите выполнить литеральный поиск, а не поиск в регулярном выражении. Вы можете использовать метод Escape для этого.

string searchText = Request.QueryString["search"].Trim(); 
string encodedValue = Server.HtmlEncode(searchText); 
string escapedValue = Regex.Escape(encodedValue); 

string contentText = Content.Text; 
contentText = Regex.Replace(contentText, @"(?s)<.*?>", string.Empty); 
contentText = Regex.Replace(contentText, escapedValue, 
    "<font class='highlight2'>$&</font>", RegexOptions.IgnoreCase); 
Content.Text = contentText; 

Есть несколько других вещей в вашем коде, которые не кажутся мне правильным (как, почему вы, кажется, постоянно удаляя все теги), но я пытаюсь сосредоточиться на ваш фактический вопрос , С этой целью я попытался внести минимальные необходимые изменения в код, чтобы проиллюстрировать мой ответ. Но есть еще одна вещь, о которой я только что хочу прокомментировать:

Не делайте этого. По крайней мере, отправьте сообщение об ошибке на консоль или восстановите исключение для вызывающего кода, с которым нужно иметь дело, но never молча проглотит их.