2008-11-19 3 views
5

Я ужасно с регулярным выражением, но у меня было попробовать и Google (и даже посмотрел в источнике Reddit), и я до сих пор застрял так вот:BBcode регулярное выражение

Моя цель состоит в том, чтобы соответствовать следуя «кодам» и заменяя их тегами HTML. Это просто регулярное выражение, за которое я застрял.

**bold text** 
_italic text_ 
~hyperlink~ 

Вот мои попытки на смелый:

^\*\*([.^\*]+)\*\*$ 

Можно ли указать, почему это не работает? Я использую синтаксис preg.

Благодаря

+0

Это не BBCode! – SaidbakR 2014-04-29 00:07:04

ответ

4

использование:

\*\*(.[^*]*)\*\* 

объяснение:

\*\*  // match two *'s 
(.  // match any character 
[^*]  // that is not a * 
*)  // continuation of any character 
\*\*  // match two *'s 

в классе символов "[]" "^" является единственным значимым, если это первый символ. так (.*) матчей ничего, (.[^*]*) это не соответствует ничего, пока буквального *

редактировать: в ответ на комментарии, чтобы соответствовать звездочку в (т.е. **bold *text**), вы должны использовать не жадный матч:

\*\*(.*?)\*\* 

Символьные классы - более эффективные не жадные совпадения, но невозможно группировать в пределах класса персонажа (see «Круглые скобки и обратные ссылки ...»)

+0

Это не соответствует строке: «Что такое ** 3 * 4 **?» просто потому, что в нем есть одна звездочка. – 2008-11-19 22:41:09

+0

Я думаю, вы хотите избавиться от этого периода. Он будет работать на **, но _ (. [^ _] *) _ Повернет __ _hi_ в hi_, не привет Mark 2008-11-19 22:51:41

3

Прежде всего, избавьтесь от^и $. Их использование будет соответствовать строке, начинающейся с **, и заканчивается на **. Во-вторых, используйте жадный квантификатор, чтобы он соответствовал как можно меньшему количеству текста, вместо того, чтобы создавать класс символов для всех символов, кроме звездочек.

Вот что я предлагаю:

\*\*(.+?)\*\* 
1
\*\*(.*?)\*\* 

, которые будут работать на жирного шрифта.

просто заменить ** с _ или ~ для других

2

Вот еще регулярное выражение: \*\*((?:[^*]|\*(?!\*))*)\*\*

Пример в Perl:

my %tag2re = (b => <<'RE_BOLD', i => '_([^_]*)_'); 
    \*\*(  # begin bold 
    (?:[^*] # non-star 
    |  # or 
    \*(?!\*) # single star 
    )*  # zero or more times 
)\*\*  # end bold 
RE_BOLD 

my $text = <<BBCODE; 
before **bold and _italic_ *text 
2nd line** after _just 
      italic_ 
**** 
**tag _soup** as a result_ 
BBCODE 

while (my ($tag, $re) = each %tag2re) { 
    $text =~ s~$re~<$tag>$1</$tag>~gsx; 
} 
print $text; 

Он печатает:

before <b>bold and <i>italic</i> *text 
2nd line</b> after <i>just 
      italic</i> 
<b></b> 
<b>tag <i>soup</b> as a result</i>

Или как html:

before bold and italic *text 
2nd line after just 
      italic 
 
tag soup as a result

интерпретация StackOverflow является:

перед тем смелов и курсива * Текст второй линии после только наклонного


тега супа в результате