2011-01-14 8 views
0

мне нужно помощь, чтобы понять регулярное выражение выражениярегулярного выражения подстроки C#

У меня есть

string = "STATE changed from [Fixed] to [Closed], CLOSED DATE added [Fri Jan 14 09:32:19 
MST 2011], NOTES changed from [CLOSED[]<br />] to [TEST CLOSED <br />]" 

мне нужно, чтобы захватить NOTES changed from [CLOSED[]<br />] to [TEST CLOSED <br />] и принимать значения CLOSED[] и TEST CLOSED в двух строковых переменных.
До сих пор я получил:

Regex NotesChanged = new Regex(@"NOTES changed from \[(\w*|\W*)\] to \[([\w-|\W-]*)\]"); 

, который соответствует только если «ПРИМЕЧАНИЯ изменено с» началось в начале и не имеет никакого «[]» в «[]», но у меня есть «[ЗАКРЫТО []] ", а также нет"
". Любые идеи о том, что изменить в регулярном выражении.

Спасибо, Шарм

+0

Есть ли у вас "
"? –

+0

Да, но это выражение не работает с «
», я как-то понимаю, что «
» в моей теме здесь – remo

ответ

1

Если «< br/>» будет там каждый раз, вы можете использовать один из моих любимых узоров (и это стоит запомнить). Узор:

delim[^delim]*delim 

выше модель будет соответствовать разделителем, а затем ничего, кроме разделителя столько раз, сколько возможно, а затем разделитель снова.

Вот регулярное выражение, которое я бы соблазн использовать:

NOTES changed from \[([^<]*)[^\]]*\] to \[([^<]*)[^\]]*\] 

На английском языке:

  • Хватает отверстие [
  • Capture # 1 все символы до < (при условии, br tag всегда есть)
  • Считывается до закрытия]
  • Повторите для s econd захвата зоны
+0

Мне понравилась идея delim. Спасибо. Это отлично работает для меня. – remo

+0

Можете ли вы направить меня к хорошему учебнику регулярных выражений, где у нас есть шаблоны, как вы упомянули. – remo

+0

@sharma. Честно говоря, я не знаю никаких хороших ресурсов, кроме www.regular-expressions.info, но этот сайт фокусируется скорее на синтаксисе, чем на шаблонах. Модель разделителя исходила из опыта. –

0

Попробуйте добавить «\[|\]» к вашему захвату последовательность в группе кронштейна.

Regex NotesChanged = new Regex(@"NOTES changed from \[(\w*|\W*|\[|\])\] to \[([\w-|\W-|\[|\]]*)\]"); 
1

Это вид Wierd ...

(\w*|\W*) 

То, что группа записи всех символов слова ноль или много раз или все символы не слово ноль или много раз

Что вы хотите если у вас есть соответствующие фигурные скобки, нужно создать шаблон, который не использует разделитель.

\[([^\]]+)\] 

Это будет соответствовать любому появлению [with some text in it], где согласованный текст является первой группой в матче.

Поскольку у вас один и тот же тип разделителей, вложенных в строку, он становится немного более сложным, и вам нужно использовать «взгляд в голову» или какое-то изменение.

((?:[^\[\]]|\[\])*) 

Это может быть будущим улучшились, но проблема здесь не может быть решена, если у вас есть [[[]]]. Вы не можете создать рекурсивное регулярное выражение. Это не так гибко. Таким образом, вам нужно либо жестко закодировать максимальную глубину, либо применить регулярное выражение несколько раз.

Достаточно исчерпывающий способ сделать это было бы

\[((?:[^\[\]]*)(?:(?=\[)(?:[^\]]*)\])?([^\]]))\] 
+0

Спасибо за эту идею, я не смог захватить ЗАКРЫТО [] и TEST ЗАКРЫТО от он, но смог их сопоставить. Но было хорошо знать о регулярном выражении, я просто стартер. Еще раз спасибо, у меня есть решение сейчас – remo

+0

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

0

Я считаю, что вы можете использовать balancing group definitions в соответствии с вложенными скобками. Я считаю, что они специфичны для .NET, по крайней мере, в этом конкретном варианте реализации. Там пример на этой странице, которую я адаптированной к введенному здесь:

class Program { 
    static void Main (string[] args) { 
     var input = "STATE changed from [Fixed] to [Closed], CLOSED DATE added [Fri Jan 14 09:32:19 MST 2011], NOTES changed from [CLOSED[]] to [TEST CLOSED ]"; 
     var regex = new Regex(@"NOTES changed from (((?'open'\[)[^\[\]]*)+((?'close-open'\])[^\[\]]*)+)*"); 

     foreach (var match in regex.Matches(input)) { 
      Console.WriteLine(match); 
     } 
    } 
} 

Печатается NOTES changed from [CLOSED[]] to [TEST CLOSED ] для меня. Обратите внимание, что в моей адаптации я оставил бит выражения, который заставляет его не соответствовать, если квадратные скобки не сбалансированы должным образом, чтобы уменьшить мой пример до минимального минимума, который удовлетворит ваш запрос ... выражение уже довольно неприятно сложный.

EDIT: Только что ваш вопрос немного отредактирован, пока я отправлял сообщения. Части регулярного выражения, которые я предоставил здесь, которые соответствуют «ничего, кроме [и]», должны быть заменены группами захвата для подстрок, которые вам нужно извлечь.

+0

Спасибо за идею, я не смог захватить ЗАКРЫТО [] и TEST CLOSED. Но было хорошо знать о регулярном выражении, я просто стартер. Еще раз спасибо, у меня есть решение сейчас – remo

0

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

NOTES changed from (?:(?:\[)?([A-Z]+\[\]))<br />\] to \[([A-Z]+\s+[A-Z]+) 

выше будет соответствовать строке NOTES changed from [CLOSED[]<br />] to [TEST CLOSED и положить CLOSED[] и TEST CLOSED в 2 отдельные группы.

Update

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

NOTES changed from (?:(?:\[)?([A-Z]+\[\])).+\[([A-Z]+\s+[A-Z]+) 

Это означает, что она будет соответствовать, как выше, только вместо того, чтобы быть конкретным относительно соответствия меток <br /> и т. д. между ними, будет соответствовать независимо от того, что находится между ними.

Смежные вопросы