2008-11-19 5 views
5

Je suis horrible avec regex, mais je l'ai eu un essai et un Google (et même regardé dans la source de reddit) et je suis toujours coincé ici va donc:BBcode regex

Mon but est de faire correspondre la après 'codes' et remplacez-les par les balises HTML. C'est juste la regex avec laquelle je suis coincé.

**bold text** 
_italic text_ 
~hyperlink~ 

Voilà mes tentatives en gras un:

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

Quelqu'un peut-il indiquer pourquoi cela ne fonctionne pas? J'utilise la syntaxe preg.

Merci

+0

Ce n'est pas un BBCode! – SaidbakR

Répondre

4

utilisation:

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

explication:

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

dans une classe de caractères "[]" "^" est significatif que si elle est le premier caractère. si (.*) correspond à quoi que ce soit, est (.[^*]*) correspondre à quelque chose jusqu'à ce que littéral *

modifier: en réponse aux commentaires pour correspondre astérisque dans les (c.-à-**bold *text**), vous auriez à utiliser un match non gourmand:

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

les classes de caractères sont des combinaisons non gourmandes plus efficaces, mais il n'est pas possible de grouper dans une classe de caractères (see "Parenthèses et références arrières ...")

+0

Cela ne correspond pas à une chaîne comme celle-ci: 'Qu'est-ce que ** 3 * 4 **?' juste parce qu'il y a un astérisque dedans. –

+0

Je pense que vous voulez vous débarrasser de la période ici. Il fonctionnera pour **, mais _ (. [^ _] *) _ Tournera __ _hi_ en hi_, pas salut Mark

+0

Votre première réponse ne devrait pas avoir un point, il correspondra à '* ** test ** '. –

3

Tout d'abord, débarrassez-vous du^et du $. L'utilisation de ceux-ci ne correspondra qu'à une chaîne commençant par ** et se terminant par **. Deuxièmement, utilisez le quantificateur gourmand pour faire correspondre le moins de texte possible, au lieu de créer une classe de caractères pour tous les caractères autres que les astérisques.

Voici ce que je propose:

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

qui fonctionnera pour le texte en gras .

** juste le remplacer avec _ ou ~ pour les autres

2

Voici une autre regexp: \*\*((?:[^*]|\*(?!\*))*)\*\*

Exemple en 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; 

Il imprime:

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>

Ou en tant que html:

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

interprétation de Stackoverflow est:

avant gras et italique texte * 2e ligne après juste italic


tag soupe à la suite

+0

Meilleure réponse jusqu'à présent. –