2010-04-12 8 views
0

J'ai une table dans SQL Server 2005 avec des centaines de lignes avec du contenu HTML. Une partie du contenu a HTML comme:Comment remplacer la balise HTML regex dans SQL Server?

<span class=heading-2>Directions</span> 

où les changements "Directions" selon le nom de la page.

Je dois changer toutes les étiquettes <span class=heading-2> et </span> en <h2> et </h2>.

j'ai écrit cette requête pour faire les changements de contenu dans le passé, mais il ne fonctionne pas pour mon problème actuel en raison de la fin d'une balise HTML:

Update ContentManager 
Set ContentManager.Content = replace(Cast(ContentManager.Content AS NVARCHAR(Max)), 'old text', 'new text') 

Est-ce que quelqu'un sait comment je pourrais accomplir la durée de h2 remplacement purement en T-SQL? Tout ce que j'ai trouvé a montré que je devrais faire l'intégration CLR. Merci!

+1

C'est probablement parce que pur T-SQL n'a pas de support pour les expressions régulières et est généralement faible en termes de manipulation de chaînes ... c'est pourquoi il y a SQL-CLR! –

+0

Ouf, s'il vous plaît ne pas utiliser TSQL pour cela :) – jvenema

+0

@timmerk - Juste pour confirmer, c'est une mise à jour ponctuelle de tags qui sont d'un modèle spécifique avec peu ou pas d'exceptions? Si certains manquent, ce sera la fin du monde ou est-ce que ce sera simplement un travail d'y aller et de corriger manuellement? – Thomas

Répondre

1

En effet T-SQL ne supporte pas nativement les expressions régulières et cela est le genre de problème dans lequel les expressions régulières seraient l'outil de choix. Tout d'abord, je dirai que le niveau de complication dans la solution dépend grandement de la cohérence de vos données. Par exemple, supposons que nous cherchons des articles à la rubrique:

Select .. 
From ... 
Where HtmlContent Like '<span class="heading-2">%' 

Cela suppose aucun espacement supplémentaire entre span et class ainsi que sans espacement supplémentaire après le guillemet final avant le support final. Nous pourrions écrire '%<span%class="heading-2"%>%' pour prendre en compte les espaces mais cela trouverait également div les étiquettes marquées comme heading-2 dans le même contenu que n'importe quelle balise d'envergure. Si ce scénario ultérieur ne doit pas se produire mais que vous disposez d'espaces variables, utilisez ce modèle révisé. Où nous allons vraiment rencontrer des problèmes est la balise de fermeture. Supposons que notre contenu ressemble à ceci:

<span class="heading-2"> Foo <span class="heading-3">Bar</span> And Gamma Too</span> .... <span class="heading-4">Fubar Is the right way!</span>... 

Il est pas si simple de trouver la balise de fermeture span correcte pour changer </h2>. Vous ne pouvez pas simplement trouver le premier </span> et le changer en </h2>. Si vous saviez que vous aviez pas span balises imbriquées, alors vous pouvez écrire une fonction définie par l'utilisateur qui le faire:

Create Function ReplaceSpanToH2(@HtmlContent nvarchar(max)) 
Returns nvarchar(max) 
As 
Begin 
    Declare @StartPos int 
    Declare @EndBracket int 

    Set @StartPos = CharIndex('<span class="heading-2">', @HtmlContent) 
    If @StartPos = 0 
     Return @HtmlContent 

    Set @HtmlContent = Replace(@HtmlContent, '<span class="heading-2">', '<h2>') 

    -- find next </span> 
    Set @StartPos = CharIndex('</span>', @HtmlContent, @StartPos) 

    Set @HtmlContent = Stuff(@HtmlContent, @StartPos, 7, '</h2>') 
    Return @HtmlContent 
End 
+2

Veuillez considérer la révision de la ligne "c'est le genre de problème dans lequel les expressions régulières seraient l'outil de choix". Les expressions régulières sont mal adaptées à l'analyse HTML ou XML. Un analyseur DOM (tel que le Html Agility Pack) est un bien meilleur choix. Encore une fois, ce n'est pas supporté par T-SQL. – TrueWill

+0

@TrueWill - Pour un simple remplacement tel que demandé, oui qui analyse certains Html/XML, les expressions régulières sont un outil beaucoup plus approprié que T-SQL. Pour l'analyse complète ou en profondeur de Html, quelque chose comme le Pack Agility serait plus approprié. Cependant, si tout ce que vous voulez faire est de trouver une seule balise dans une goutte de texte, un analyseur Html est susceptible d'être exagéré. – Thomas

+2

De cette façon, il y a la folie. http://www.codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html – TrueWill

-3

Gah, utilisez jquery! Ne pas rendre la vie difficile .. il y a un exemple de code de remplacement sur la page d'accueil de jquery et vous pouvez simplement inclure le jquery-1.4.2.js dans la section <head>

0

Je ne suis pas vraiment fort dans SQL Server, mais voici comment je voudrais essayer de faire :

UPDATE TableName SET FieldName = REPLACE(FieldName ,'<span class=heading-2>', '<h2>') SET FieldName = REPLACE(FieldName, '</span>', '</h2>') 

Il faudrait peut-être 2 UPDATE émises, je ne suis pas sûr que vous pouvez utiliser sur le même champ de cette façon. L'OP a dit TOUTES les occurrences du texte. Réglez-moi directement s'il me manque quelque chose.

Bien sûr, s'il y a d'autres textes <span class=heading-2> ou </span> que vous ne voulez pas modifier, cela ne fonctionnera pas.

1

Si vous êtes positif que tous du HTML est (et sera toujours) XHTML valide et que vous utilisez SQL Server 2005 ou version ultérieure, vous pourriez être en mesure de jeter les colonnes à un ensemble de données XML tapez et utilisez XQuery.Voir http://msdn.microsoft.com/en-us/library/ms345117%28SQL.90%29.aspx

(caveat. Je ne l'ai pas essayé)

Je pense que la meilleure réponse, cependant, est le commentaire de Michael Petito. Je voudrais écrire une application pour ce faire et utiliser le Html Agility Pack. Cela fournira une solution permanente et maintenable qui fonctionnera dans presque tous les cas.

(Si c'est un one-shot et vous ne se soucient pas de précision, puis choisissez votre poison.)

+0

Comment pouvez-vous affirmer que l'utilisation d'expressions régulières est «folie» et que vous vous retournez et que vous suggérez d'analyser le code HTML comme code HTML?! Si le code HTML n'est pas bien formé, il ne sera pas analysé en XML! Les chances de ce travail sont inférieures d'un ordre de grandeur s'il y a même un petit problème dans le balisage que d'utiliser simplement la recherche standard ou regex. Désolé, mais c'est une solution fragile. – Thomas

+0

TBH, je reprends ma downvote, si vous avez simplement suggéré d'utiliser le Pack Agility comme vous l'avez fait vos commentaires. Bien que je pense que c'est excessif, c'est une solution nettement meilleure que d'essayer d'utiliser le type de données XML. – Thomas

+0

@Thomas: S'il vous plaît noter que ma réponse commence par "** Si le code HTML est valide XHTML **". L'OP n'a pas mentionné l'origine du HTML. Si c'est connu pour être XHTML ou bien formé, cela peut valoir la peine d'être considéré. Sinon, ça ne marchera pas. Dans ce dernier cas, j'écrirais une application (comme M. Petito l'a suggéré) et j'utiliserais le pack d'agilité Html. J'ai dû maintenir des solutions à 95% et du code «temporaire» rapide et corrompu qui a survécu; Je préfère ne pas mettre les autres à travers ça. – TrueWill

Questions connexes