2010-08-03 5 views
0

J'ai l'expression régulière suivante pour trouver un mot dans le texte et le mettre en surbrillanceQuel est le problème avec cette expression régulière?

Utilisation de la surface du mot à des fins de test.

/((?<=[\W])surface?(?![\w]))|((?<![\w])surface?(?=[\W]))/iu 

Il correspond à toutes les occurrences dans le texte suivant.

surface CoP-20-70-0000-04-02_Pre-Run_Tool_Verification_Programming_and_surface_Tare surface_revC.pdf

Mais si je change la première apparition de la surface pour contenir une lettre majuscule, il correspond uniquement à la première occurence .

Surface-CoP-20-70-0000-04-02_Pre-Run_Tool_Verification_Programming_and_surface_Tare surface_revC.pdf

Ou si je mets une lettre majuscule dans certains des autres occurences il correspond à cela.

Surface-CoP-20-70-0000-04-02_Pre-Run_Tool_Verification_Programming_and_Surface_Tare surface_revC.pdf

+0

Pouvez-vous utiliser '\ b' à la place de votre lookahead/lookbehind? – strager

+2

FYI, '/ surface? /' Correspond à '" surfac "'. 'e?' rend le 'e' optionnel. Peut-être que vous voulez '(surface)?', Ou peut-être que vous voulez quelque chose d'autre (ce n'est pas clair). – polygenelubricants

Répondre

1

Je ne sais pas ce que vous essayez d'atteindre là-bas, mais peut-être votre problème est que \w comprendra _ (et \W l'exclura).

Peut-être essayer ceci:

/(?<![a-z])surface(?![a-z])/iu 

Ou ceci:

/(?<=[\W_])surface(?=[\W_])/iu 

Sinon, s'il vous plaît fournir plus de détails sur exactement ce que vous ne/ne voulez pas correspondre.


Mise à jour: donné cette information:

surface2010 ne doit pas être mis en correspondance

Dans ce cas, je suppose que vous voulez:

/(?<=\b|_)surface(?=\b|_)/iu 

(depuis seulement \b exclurait une correspondance contenant "... et _surface_Tare ... "donc nous ajoutons l'alternance avec _ pour l'inclure.)

+0

Je veux faire correspondre des mots entiers dans le texte, pas surfer dans la surface, etc. Mots suivis ou précédés par l'espace ou tout autre caractère non-mot. Je l'utilise pour mettre en évidence ces mots dans le texte. Devrait être insensible à la casse, c'est quand le problème se produit. Il doit également correspondre au mot lui-même, lorsqu'il n'y a pas d'autres mots ou caractères qu'il n'a pas – oddi

+0

Définir "caractère non-mot". Dans regex, un caractère de mot ('\ w') est' [A-Za-z0-9_] 'qui pourrait ne pas être ce que vous voulez - d'où les deux options que j'ai posté ci-dessus. Le premier d'entre eux (ou une légère adaptation) devrait vous donner ce que vous voulez. (Le drapeau 'i' le rend insensible à la casse, et il est peu probable que PHP ait un bug dans cela.) –

0

Ai-je raté quelque chose?

/\bsurface\b/i 
+0

Cela ne correspondra pas' _surface_' car '\ b' est un changement entre' \ w' et '\ W' et le caractère '_' est inclus dans' \ w'. –

+0

@Peter Boughton, Alors faites quelque chose comme: '/ (? <= _ | \ B) surface (? = _ | \ B)/i' – strager

+0

Oui, ce qui est similaire à mon' [\ W_] ', bien que cela ne correspondra pas seulement à "surface" - mais probablement le premier que j'ai énuméré est préféré de toute façon. Besoin de clarification de la part de l'OP si "surface2010" doit être apparié ou non. –

0

Vous voulez faire correspondre surface insensible à la casse à moins qu'elle soit précédée ou suivie immédiatement par une lettre ou un chiffre? Essayez ceci:

/(?<![A-Za-z0-9])surface(?![A-Za-z0-9])/i 

je l'ai laissé le modificateur /u (ce qui provoque l'expression régulière et la chaîne de sujet à traiter en UTF-8) parce que vous semblez traiter avec du texte ASCII pur.\w, \W et \b ne sont pas affectés par /u de toute façon.