2009-09-03 4 views
1
(\[(c|C)=)(#?([a-fA-F0-9]{1,2}){3})\](.*)\[/(c|C)\] 

Я хочу, чтобы это выражение соответствовало тексту типа: «Это [c = FFFFFF] белый текст [/ c] и [C = # 000] черный текст [/ C]."Regex matching too much

Он соответствует одному BB-коду, но если после друг друга (как в примере) больше, он будет создавать совпадение (1 совпадение) обеих последовательностей BB-кода. (от [c = FFFFFF] wh ... до ... ck text [/ C])

Почему это происходит? Кроме того, как сделать точку (.) Включать новые строки в C#?

+0

Что вы хотите совместить с «FFFFFF и # 000» или хотите «белый тест FFFFFF и черный текст № 000»? – skyfoot

ответ

3

Если вы не заботитесь о вложенных тегов, вы можете сделать это:

(\[[cC]=)(#?([a-fA-F0-9]{3}){1,2})\](.*?)\[/[cC]\] 
//          ^- lazy match 

Если вы хотите обрабатывать вложенные теги с регулярным выражением, проверьте this article на коде проекта.

1

Это происходит потому, что RE - greedy; он всегда будет пытаться создать максимально возможное совпадение.

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

2

Точка соответствует символам новой строки, если вы установили опцию RegexOptions.Singleline (more on that here).

0

Вам нужно ленивое регулярное выражение, чтобы не забрать все [C] тегов

Попробуйте

\[c=(#?.*?)\](.*?)\[/c\] or 
\[c=(#?\w*?)\](\w*?)\[/c\] 

Вы должны установить параметры вашего объекта регулярного выражения для ingnore случая.

0

Regex - это быстрый грязный способ сделать это, и здесь нужно использовать .*?, а не только .*. Однако, если вы хотите, чтобы более надежное решение, вероятно, было проще без регулярного выражения. В C# вы оказались способным делать вложенные структуры, но это не значит, что на самом деле это просто. Было бы лучше использовать лексический парсер и построить DOM. Скорее всего, код будет легче читать и поддерживать.