2008-11-17 6 views
2

Quelqu'un pourrait-il me montrer une expression régulière qui regarderait à travers ce document et sélectionner la valeur href de chaque href qui a RELATION_ID à la fin de celui-ci? Ensuite, si elle le fait, je dois obtenir l'ID qui est avant le point d'interrogation (exemple href="dctm://ISDOFSDdev/ 37004e1f800021f3 ?DMS_OBJECT_SPEC=RELATION_ID «)Construire une expression régulière pour trouver l'id dans un href

Merci

<?xml version="1.0" encoding="utf-8"?> 
<?dctm xml_app="elearningContent"?> 
<!DOCTYPE OnlineContent PUBLIC "-//ISDOFSD//DTD Online Content//EN" "file:C:/dmExport/New%20Folder%20(2)/ISDOFSDdev/elearningContent/OnlineContent.dtd"> 
<OnlineContent outputclass="Graphic Down" id="OnlineContent_955627C91D8743B98DCB8BD9BE379DE8"> 
    <title>Text and Popup</title> 
    <OnlineContentBody> 
     <lcInstruction id="lcInstruction_770F26218C064A84BFA1813562173970"> 
      <p>This is an example of a plain text screen with an attached popup.</p> 
      <p> 
       Popups are used to display additional content in a popup window. A <xref scope="local" type="topic" format="dita" href="dctm://ISDOFSDdev/37004e1f800021f3?DMS_OBJECT_SPEC=RELATION_ID">link is provided</xref> in the main text of the screen, which may clicked on to open a popup. A screen may contain <xref scope="local" type="topic" format="dita" href="dctm://ISDOFSDdev/37004e1f800021f4?DMS_OBJECT_SPEC=RELATION_ID">more than one popup</xref>. 
      </p> 
     </lcInstruction> 
    </OnlineContentBody> 
    <OnlinePopup id="OnlinePopup_AFE53E2CACBF4D8196E6360D4DDB6B70"> 
     <title>A Popup</title> 
     <OnlinePopupBody> 
      <p>This is an example of popup content.</p> 
      <p>A popup may contain one or more paragraphs of text. They may also contain lists, like this:</p> 
      <ul id="ul_7812991BBBDD4995B7499A9557C4EA9C"> 
       <li id="li_E83BDB28EC494B98BFF3DD5924AF855E">An item in a list</li> 
       <li id="li_270F2A3A85BA4E6EBF98CB4023344475">Another item in a list</li> 
      </ul> 
      <p>A numbered list is demonstrated in the second popup.</p> 
     </OnlinePopupBody> 
    </OnlinePopup> 
    <OnlinePopup id="OnlinePopup_5AE081BFB97043CE99F39A9E4A063332"> 
     <title>Another Popup</title> 
     <OnlinePopupBody> 
      <p>This is the second popup on this screen, containing a numbered list.</p> 
      <ol id="ol_EF18C080E7CC40B7998DEB75772367A6"> 
       <li id="li_91B42F1B886B4CF887C001577C14B3F0">An item in a list</li> 
       <li id="li_95C4F32E093843FAB985A3F6981A7D07">Another item in a list</li> 
      </ol> 
     </OnlinePopupBody> 
    </OnlinePopup> 
</OnlineContent> 
+0

Quelle langue utilisez-vous? Perl, Java, Python ...? Je demande parce que chaque langue a de légères variations dans leur syntaxe regex. – grieve

+1

Vous devez faire attention avec les expressions régulières et les données complexes. Les expressions régulières sont sensibles à la fois à l'espace blanc et à la casse, et donnent presque toujours de mauvais résultats si elles correspondent à quelque chose que vous n'attendiez pas. XPath et les fonctions d'analyse d'url seront certainement plus fiables. – Cybis

Répondre

4

Vous pouvez utiliser cette expression regex:

[a-fA-F0-9]+(?=\?DMS_OBJECT_SPEC=RELATION_ID) 

qui correspond au numéro du hexadécimal immédiatement avant la chaîne de requête.

Je suggère également d'utiliser XPath pour faire cela sur regex.

+0

J'ai mal lu la question, désolé – Will

+0

Merci cela fonctionne bien maintenant. – joe

1

Quelque chose comme:. href=".*/([^"?/]*)?[^"]*RELATION_ID[^"]*" Cela suppose que vous êtes être cohérent en utilisant des guillemets doubles pour vous les attributs. Cela devrait être perl & java amical.

le ([^"?/]*) capturera le bit entre la barre et le point d'interrogation. en java, utilisez Matcher.group(int) pour avoir la valeur. Si vous essayez d'obtenir plusieurs valeurs du même document, regardez Matcher.find(int).

+0

Merci! Y at-il un moyen facile d'obtenir facilement l'ID qui se trouve entre le slash et le point d'interrogation? – joe

1

Il n'est peut-être pas prudent d'attaquer ceci avec une regex simple. XPath avec une fonction intégrée d'analyse d'url pourrait être une meilleure solution.

Comme indiqué précédemment, la meilleure solution dépend de la langue que vous utilisez.

1

peut-être quelque chose comme ça href = "(. +?)/(. +?) \? (. +?) RELATION_ID" et utiliser le deuxième match si vous cherchez seulement pour la partie id (37004e1f800021f3 dans votre exemple)

1

Voici une solution python:

expr = re.compile('href=.*?/(.*?)\?.*?=RELATION_ID', re.MULTILINE) 

for x in expr.finditer(test_string): # iterate through all matches 
    s = x.group(1) # get the one and only group of the match 
    ss = s.split("/") # split off the ISDOFSDdev 
    s = ss[len(ss) - 1] # grab the last element 
    print s # print it 

sortie où test_string est la chaîne que vous avez affichée:

37004e1f800021f3 
37004e1f800021f4 

Encore une fois cela est en python, mais l'esprit h toute bibliothèque regex moderne, vous devriez être capable de le reproduire.

Il est extrêmement difficile d'obtenir une expression régulière qui va simplement sortir l'ID. Je ne dis pas que c'est impossible, mais il est souvent plus facile de se rapprocher de l'expression régulière, puis de séparer ce dont vous avez besoin de la sous-chaîne que l'expression régulière vous donne.

Documentation sur le module python regex.

+0

Well Will a montré une expression régulière extrêmement facile qui sort l'ID. :) :( – grieve

3

Comme vous avez des données XML, pourquoi ne pas utiliser une feuille de style XSLT ?. Cet exemple sélectionne la valeur des attributs souhaités. Cet exemple utilise uniquement les fonctions XPath 1.0 qui sont quelque peu limitées. Il affiche les valeurs des attributs href souhaités.

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     > 
     <xsl:output method="text" indent="no"/> 
     <xsl:template match="*[@href]"> 
      <xsl:if test="contains(@href, 'RELATION_ID')"> 
       <xsl:value-of select="@href"/> 
      <xsl:text>&#xa;</xsl:text> 
      </xsl:if> 
      <xsl:apply-templates select="*"/> 
     </xsl:template> 
     <xsl:template match="*"> 
      <xsl:apply-templates select="*"/> 
     </xsl:template> 
</xsl:stylesheet> 

Considérant que vous nommez « exemple.xml » le fichier donné et « exemple-xslt.xsl » la feuille de style XSLT à condition que vous pouvez utiliser la ligne suivante pour enregistrer le résultat dans un fichier « out.txt » utilisant MSXSL.exe:

C:\Documents and Settings\fer\Escritorio>msxsl.exe -xw example.xml example-xslt.xsl > out.txt 

Edit:. suivant est le XSLT en utilisant v2.0 XPath qui vous permet de utiliser la puissance des expressions régulières à l'intérieur funcions manipulation de chaîne Le résultat est l'ID dans l'URL que vous recherchez (au lieu de toute la valeur des attributs href).

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:fn="http://www.w3.org/2005/xpath-functions" > 
     <xsl:output method="text" indent="no"/> 
     <xsl:template match="*[@href]"> 
      <xsl:if test="fn:contains(@href, 'RELATION_ID')"> 
       <xsl:value-of select="fn:replace(@href,'.*/([^/]*)\?.*', '$1')"/> 
       <xsl:text>&#xa;</xsl:text> 
      </xsl:if> 
      <xsl:apply-templates select="*"/> 
     </xsl:template> 
     <xsl:template match="*"> 
      <xsl:apply-templates select="*"/> 
     </xsl:template> 
</xsl:stylesheet> 

Il n'y a pas beaucoup de processeurs v2.0 XSLT libre là-bas, mais AltovaXML-2008 est l'un d'entre eux. la ligne de commande suivante vous donne le résultat attendu.

C:\Documents and Settings\fer\Escritorio>AltovaXML -xslt2 example-xslt.xsl -in example.xml 
0

d'abord trouver l'attribut href en utilisant cette expression rationnelle: href = "[^ =] * = RELATION_ID"

Une fois que vous avez une collection de ces attributs, utilisez l'expression rationnelle suivante pour trouver l'ID: DCTM: [ ? ^] *

Explication de la première regex

href = ": Faites correspondre les caractères "href ="" littéralement
[^ =] *: correspond à tout caractère qui n'est pas "=" entre zéro et durée illimitée
= RELATION ___ ID: Faire correspondre les caractères "= RELATION_ ID "littéralement.

Explication de seconde regex

DCTM:: Faites correspondre les caractères "DCTM:" littéralement
* [^?]: "?" Correspond à tout caractère qui n'est pas entre zéro et des temps illimités.

Si vous allez utiliser des expressions régulières souvent, vous devriez sérieusement envisager l'achat d'Regex amis à http://www.regexbuddy.com/

Questions connexes