2010-05-06 2 views
1

J'ai une chaîne comme
Pakistan, officially the <a href="Page.aspx?Link=Islamic Republic of Pakistan">Islamic Republic of Pakistan</a>Comment puis-je éviter un modèle de chaîne spécifique d'être remplacé par Regex.Replace()

Maintenant, je suis en utilisant
System.Text.RegularExpressions.Regex.Replace(inputText, "(\\bPakistan\\b)", "something"); pour remplacer le Pakistan en dehors des balises. Mais je ne veux pas remplacer le Pakistan sur les étiquettes <a></a>.
Edit: une chaîne réelle

Pakistan (ourdou: پاکستان), officiellement la République islamique du Pakistan, est un pays en Asie du Sud. Il a un 1046 km (650 mi) côte le long de la mer d'Oman et le golfe d'Oman dans le sud et est bordée par l'Afghanistan et de l'Iran à l'ouest, Inde à l'est et la Chine dans l'extrême nord-est. [6] Le Tadjikistan se trouve également à très proche du Pakistan mais est séparé par le couloir étroit Wakhan .


et un tableau de chaînes

string[] links={"Pakistan","Islamic Republic","Republic of Pakistan","South Asia","Arabian Sea","Gulf","Oman","Gulf of Oman","the south","in the south","Afghanistan","Iran","the west","in the west","west India","the east","China","Tajikistan","the narrow","Wakhan Corridor","Central Asia","the Middle","Middle East","the Middle East"} 

Je veux remplacer toutes les occurrences de chaque chaîne dans ce tableau avec <a href="page.aspx?link=thisString">thisString</a>. et je ne pouvais pas ajouter correctement des liens à des chaînes comme "République du Pakistan" où le Pakistan est aussi une autre chaîne dans ce tableau.

Répondre

1

Bien que la solution ne fonctionne pas @ Chris exactement ici, mais vous pouvez utiliser de cette façon.

string content = "Pakistan is <a href=\" Pakistan is\">Pakistan an islamic country</a>"; 
string content2= Regex.Replace(content,@"\bPakistan\b", "India"); 
string content3 = Regex.Replace(content2, @"(?<=\<\s*a[^<]+)\bIndia\b(?=.*?\>)", "pakistan");   
Console.WriteLine(content3);  

mais ce n'est pas une solution très efficace.

+0

Peut-être pas très efficace mais facile à comprendre et à mettre en œuvre. Merci –

+0

Je l'ai utilisé comme ceci inputText = Regex.Replace (inputText, @ "(? <= \ <\ S * a [^ <] +) \ bStringToReplace \ b (? =. *? \>)", "DBPT "); inputText = System.Text.RegularExpressions.Regex.Replace (inputText, "(\\ bStringtoReplace \\ b)", Remplacement); inputText = Regex.Replace (inputText, @ "(? <= \ <\ s * a [^ <] +) \ bDBPT \ b (? =. *? \>)", StringtoReplace) –

2

Si vous essayez de faire quelque chose dans le contexte de la syntaxe HTML, utilisez un analyseur HTML.

0

Obtenez chaque ligne de texte dans une chaîne A

Retirez le mors <a></a> et le stocker dans la chaîne B

Exécutez votre Regex sur le reste du texte dans la chaîne A

retour A + B

+0

L'emplacement de sera perdu. –

+0

Non, vous ne devez pas, vous devez afficher un exemple de code simple avec des données d'échantillon claires. –

+0

Vous avez raison dans cette chaîne. Mais «» n'apparaît pas nécessairement à la fin et il existe plusieurs blocs «». –

1

Voici comment vous pouvez faire le contraire de ce que vous demandez (ne remplacez que les instances à l'intérieur des tags):

content = Regex.Replace(content, @"(?<=\<\s*a[^>]+)\bPakistan\b(?=.*?\>)", "India"); 

Ceci est très non testé et pas ce que vous voulez, mais il pourrait vous donner quelques conseils. Cela utilise zero-width lookaround assertions. Je suis sûr qu'il y a beaucoup d'autres façons de le faire.

Ceci pousse vraiment les limites de regex. Vous devriez probablement utiliser un analyseur HTML.

Edit: en utilisant lookbehind négatif, cela semble fonctionner (s'il vous plaît le tester!):

content = Regex.Replace(content, @"(?<!\<\s*a[^>]+)\bPakistan\b", "India"); 
+0

Est-ce que l'expression rationnelle C# autorise des expressions de largeur variable dans les lookbehinds négatifs? La plupart des moteurs regex qui supportent lookbehinds n'autorisent pas les expressions de largeur variable (du fait de ne pas savoir jusqu'où ils se trouvent pour tenter de les faire correspondre). – Amber

+0

Ma compréhension potentiellement erronée de la "largeur nulle" était que cela signifiait que l'assertion ne capturait rien. L'exemple .NET regex à http://msdn.microsoft.com/en-us/library/bs2twtah.aspx#sectionToggle8 semble utiliser des expressions à largeur variable: "(?

+0

@Dav: .NET est presque unique parmi les saveurs regex en ce sens que vous pouvez utiliser n'importe quelle expression que vous aimez dans un lookbehind. @Chris: il est plus correct de dire qu'une assertion de largeur nulle (comme un lookbehind) * ne consomme * rien. Capturer est autre chose. –

2

Pour la première partie de votre question, je correspondre soit un lien ou le mot cible:

Regex r = new Regex(@"<a\s+.*?</a>|\bPakistan\b"); 

Puis j'utiliser un MatchEvaluator pour vérifier lequel j'appariés et remplacer en conséquence: si c'est un lien, rebranchez-le; si c'est le mot cible, linkify.

Pour la deuxième partie, vous pouvez Join les chaînes du tableau dans une alternance regex, comme ceci:

string regex = String.Format(@"\b({0})\b", String.Join("|", links)); 

Rappelez-vous simplement que l'alternance retourne la première alternative correspondant, pas la plus longue. Si aucune alternative A est un préfixe de remplacement B, B doivent être énumérés avantA. Par exemple, the Middle East devrait apparaître avant the Middle dans votre liste.

Questions connexes