2009-06-01 10 views
1

Je tente d'écrire un composant CF qui analysera le texte wikiCreole. J'ai du mal à trouver les bonnes correspondances avec certaines de mes expressions régulières. Je me sens comme si je pouvais juste faire la tête autour du premier que le reste cliquera. Voici un exemple:Correspondance Regex dans ColdFusion OU condition

Ce qui suit est entrée échantillon:

You can make things **bold** or //italic// or **//both//** or //**both**//. 

Character formatting extends across line breaks: **bold, 
this is still bold. This line deliberately does not end in star-star. 

Not bold. Character formatting does not cross paragraph boundaries. 

Ma première tentative a été:

<cfset out = REreplace(out, "\*\*(.*?)\*\*", "<strong>\1</strong>", "all") /> 

Je réalise qu'il ne correspondrait pas à où le ** est pas donné, et il devrait se terminer là où il y a deux retours chariot.

J'ai donc essayé ceci:

<cfset out = REreplace(out, "\*\*(.*?)[(\*\*)|(\r\n\r\n)]", "<strong>\1</strong>", "all") /> 

et il est proche, mais pour une raison quelconque, il vous donne ceci:

You can make things <strong>bold</strong>* or //italic// or <strong>//both//</strong>* or //<strong>both</strong>*//. 

Character formatting extends across line breaks: <strong>bold,</strong> 
this is still bold. This line deliberately does not end in star-star. 

Not bold. Character formatting does not cross paragraph boundaries. 

Toutes les idées? PS: Si quelqu'un a des suggestions pour de meilleures étiquettes, ou un meilleur titre pour ce poste, je suis tout ouïe.

Répondre

6

Le [...] représente une classe de caractères, donc ceci:

[(\*\*)|(\r\n\r\n)] 

est effectivement la même chose que ceci:

[*|\r\n] 

à-dire qu'elle correspond à un "*" et "|" n'est pas une alternance.

Un autre problème est que vous remplacez le double saut de ligne. Même si votre match a réussi, vous finirez par fusionner des paragraphes. Vous devez le restaurer ou ne pas le consommer en premier lieu. J'utiliserais un lookahead positif pour faire le dernier.

En Perl je l'écrire de cette façon:

$string =~ s/\*\*(.*?)(?:\*\*|(?=\n\n))/<strong>$1<\/strong>/sg; 

Prendre une conjecture sauvage, ColdFusion ressemble probablement ceci:

REreplace(out, "\*\*(.*?)(?:\*\*|(?=\r\n\r\n))", "<strong>\1</strong>", "all") 
+0

Cela ne semble correspondre à rien du tout, mais je vois ce que vous dites à propos du [] correspondant seulement un char. Je ne suis pas sûr de ce que le fait: est-il possible, est-il possible que la syntaxe pour cela soit différente dans CF? –

+0

Le (?: ...) est un regroupement sans capture. Il limite l'alternance entre le "**" littéral et le "\ n \ n". D'après ce que je peux voir, la seule différence de syntaxe (ici) est que dans CF un "." correspond à newline où, en Perl, ce n'est pas le cas par défaut. –

+0

D'accord je l'ai changé à ceci: \ * \ * ([^ *] *?) (?: \ * \ * ((? = \ R \ n)) et il commence à fonctionner, sauf que je pense il doit être changé et ne chercher que les retours chariot double. Deux d'affilée est un nouveau paragraphe. Donc serait-ce: \ * \ * ([^ *] *?) (?: \ * \ * | (? = (\ R \ n) {2})) est-ce exact? –

0

J'utilise toujours un regex web-page. Il semble que je pars à partir de zéro chaque fois que j'ai utilisé regex. Essayez d'utiliser '$ 1' au lieu de \ 1 pour celui-ci - le remplacement est légèrement différent ... mais je pense que le modèle est ce dont vous avez besoin pour travailler.

Se rapprocher avec ceci: (.? )

** ** | // (.?) //

La partie délicate est la // ** ou ** //

Ok, d'abord pour vérifier // // gras alors // gras // puis en gras, puis // gras //

** // (. ) // ** |?. // ** () ** // | ** () ** |.?. // () //

+0

Merci . J'utilise une page de test comme celle-ci, je n'arrive pas à trouver la bonne regex pour faire ce que j'essaie de faire. –

+0

J'ai essayé le $ 1 mais il a mis un $ 1 littéral dedans là au lieu du match. –

+0

Le remplacement ne fonctionne pas tout à fait comme je m'y attendais ... – Kieveli

1

Vous devriez vraiment? changer votre

(.*?) 

à quelque chose comme

[^*]*? 

pour correspondre à tout caractère sauf le *. Je ne sais pas si c'est le problème, mais ça pourrait être n'importe quel caractère. est en train de manger une de tes étoiles. Il s'agit également d'une «meilleure pratique» généralement acceptée lorsque vous tentez d'équilibrer les caractères correspondants tels que les balises start/end html double star ou html pour les exclure explicitement de votre jeu de correspondance pour le texte interne.* Clause de non-responsabilité, je n'ai pas testé cela dans ColdFusion pour les nuances du moteur regex - mais l'idée devrait être vraie.

+0

Merci pour cela. Cela semble fonctionner un peu mieux. Cela correspondrait-il à un retour chariot? Si oui, existe-t-il un moyen d'exclure cela? –

+0

Cela échouerait pour "** A * B **" qui (vraisemblablement) devrait être remplacé par "A * B". –

0

Je trouve cette application extrêmement utile quand je suis faire quelque chose avec regex: http://www.gskinner.com/RegExr/desktop/ Toujours pas d'aide avec votre problème réel, mais pourrait être utile à l'avenir.

1

Je sais que cette question est plus, mais en réponse à l'endroit où Ryan Guill a dit: «J'ai essayé le 1 $, mais il mettre un littéral 1 $ là au lieu du match » pour ColdFusion, vous devez utiliser \1 au lieu de $1

Questions connexes