2009-12-11 4 views
1

J'ai une regex qui analyse un morceau de texte pour une liste de mots-clés définis dans un db. Je crée dynamiquement mon regex du db pour obtenir ceci:Problème Regex avec des caractères réservés dans C#

\b(?:keywords|from|database|with|esc\@ped|characters|\@ss|gr\@ss)\b 

Notez que les caractères spéciaux sont échappés. Cela fonctionne pour la grande majorité des cas, SAUF si le premier caractère du mot-clé est un caractère spécial regex comme @ ou $. Donc, dans l'exemple ci-dessus, @ss ne sera pas reconnu, mais gr @ ss et esc @ ped le feront.

Des idées pour faire fonctionner cette regex pour ces cas spéciaux? J'ai essayé à la fois avec et sans échapper les caractères spéciaux dans la chaîne regex, mais en vain.

Merci à l'avance,

David

+1

@ est un caractère spécial regex? – Amarghosh

+0

Vous pourriez vouloir échapper à la barre oblique inverse en premier lieu: quelque chose comme '\\ +' – Amarghosh

+0

Bon point - @ n'est pas un caractère spécial regex. Toujours coincé cependant! Double-échapper ne fonctionne pas non plus, semble-t-il. D'autres idées? –

Répondre

4
new Regex(@"(?<=^|\W)(?:keywords|from|database|with|[email protected]|characters|@ss|[email protected])(?=\W|$)") 

correspondront. Il vérifie s'il existe un caractère non-mot (ou début/fin de chaîne) avant/après le mot-clé à rechercher. J'ai choisi \W sur \s en raison de la ponctuation et d'autres caractères non-mots qui pourraient constituer une limite de mot.

Edit: Encore mieux (! Grâce à Alan Moore - les deux versions produiront les mêmes résultats):

new Regex(@"(?<!\w)(?:keywords|from|database|with|[email protected]|characters|@ss|[email protected])(?!\w)") 

Les deux ne parviennent pas à égaler @ass dans [email protected] ce qui est probablement ce que vous voulez.

+0

Oui cela semble correspondre à la même chose que @ "(\ b | ^) (?: keywords | from | database | avec | esc @ ped | caractères | @ss | gr @ ss) (\ b | $) " – asgerhallas

+0

Non, votre regex ne correspond qu'à" @ ss "au début de la chaîne –

+0

Je suis désolé, vous avez raison, vos réponses sont correctes. – asgerhallas

2

Lorsque vous obtenez les mots-clés de la base de données, leur échapper avec Regex.Escape avant de créer la chaîne Regex.

+0

Qui ne s'échappe pas @ – asgerhallas

+0

Très bon appel asgerhallas. Pourquoi le @ étant échappé à la 1ère place? –

+0

J'échappais à une liste de personnages qui semblaient causer un problème - j'ai aussi essayé sans leur échapper. Regex.Escape n'échappe que aux métacaractères réservés - mais la regex ne correspond toujours pas aux chaînes commençant par des caractères comme @ –

1

Le signe @ ne désigne pas une limite de mot.

Utilisation: (\ s | ^) (?: mots-clés | de | base de données | avec | esc @ ped | caractères | @ ss | gr @ ss) (\ s | $)

Testé avec les éléments suivants programme:

static void Main(string[] args) 
    { 
     string pattern = "(\\s|^)(?:keywords|from|database|with|[email protected]|characters|@ss|[email protected])(\\s|$)" 
     var matches = Regex.Matches("@ss is [email protected] is [email protected] keywordsnospace keywords", pattern); 
     foreach (Match match in matches) 
     { 
      Console.WriteLine(match.Groups[2]); 
     } 
    } 

Donner le résultat:

@ ss

gr @ ss

esc @ ped

mots-clés

+0

Cela ne semble pas fonctionner. Il ne correspond pas à "keywords" ou "gr @ ss" ou "@ss". D'autres idées? –

+0

Hmm. Je viens d'essayer ça. Ça a marché. Deux secondes, je vais essayer à nouveau. – asgerhallas

+0

Désolé, c'est: (\\ s | ^) (?: mots-clés | de | base de données | avec | esc @ ped | caractères | @ss | gr @ ss) Mise à jour de la réponse. – asgerhallas

Questions connexes