2017-03-21 2 views
4

Regular Expression ' mit '' zu ersetzen, wenn es in <xsl: sonst ' sollte bleiben, wie es ist.
Code Snippet:
Regex Apostroph mit Apostroph zweimal zu ersetzen, wenn es innerhalb von <xsl: oder <XSL:

public static void main(String[] args) { 
     String replaceSingleQuoteInsideXsltCondition = "(<\\s*?xsl\\s*?:.*?=.*?)(')(.*?)(')(.*?>)"; 
     String dummyXSLT = "<p>Thank you for sending us <xsl:for-each select=\"catalog/cd[artist='Bob Dylan']\"> " + 
       "paper's to prove your <span class=\"highlight\"><xsl:if test=\"D01 ='Y'\">Income</xsl:if></span> <span class=\"highlight\"><xsl:if test=\"D02 ='Y'\">&#160;and&#160;" + 
       "</xsl:if></span><span class=\"highlight\"><xsl:if test=\"D03 ='Y'\">Citizenship and/or Identity</xsl:if></span>. " + 
       "We need a little more information to finish your application. Addition of few words like 7 o'clock, employees' or employ's and child's and 'xyz and 'hello'</p>" + 
       "contact number for inquiry = '478965152' and email id = '[email protected]'" + 
       "<xsl:template match=\"num[ . = 3 or . = 5]\"/></xsl:stylesheet><xsl:if test=\"contains($search, 'Web Developer') and (contains($expSearch, 'Computer') or contains($expSearch, 'Information') or contains($expSearch, 'Web'))\">" + 
       "<xsl:if test=\"((node/ABC!='') and (normalize-space(node/DEF)='') and (normalize-space(node/GHI)=''))\"> just a dummy sample.</xsl:if>"; 
     System.out.println(dummyXSLT.replaceAll(replaceSingleQuoteInsideXsltCondition, "$1''$3''$5")); 
    } 

Tatsächliches Ergebnis von oben Code:

<p>Thank you for sending us <xsl:for-each select="catalog/cd[artist=''Bob Dylan'']"> paper's to prove your <span class="highlight"><xsl:if test="D01 =''Y''">Income</xsl:if></span> <span class="highlight"><xsl:if test="D02 =''Y''">&#160;and&#160;</xsl:if></span><span class="highlight"><xsl:if test="D03 =''Y''">Citizenship and/or Identity</xsl:if></span>. We need a little more information to finish your application. Addition of few words like 7 o'clock, employees' or employ's and child's and 'xyz and 'hello'</p>contact number for inquiry = '478965152' and email id = '[email protected]'<xsl:template match="num[ . = 3 or . = 5]"/></xsl:stylesheet><xsl:if test="contains($search, ''Web Developer'') and (contains($expSearch, 'Computer') or contains($expSearch, 'Information') or contains($expSearch, 'Web'))"><xsl:if test="((node/ABC!='''') and (normalize-space(node/DEF)='') and (normalize-space(node/GHI)=''))"> just a dummy sample.</xsl:if> 

Erwartetes Ergebnis:

<p>Thank you for sending us <xsl:for-each select="catalog/cd[artist=''Bob Dylan'']"> paper's to prove your <span class="highlight"><xsl:if test="D01 =''Y''">Income</xsl:if></span> <span class="highlight"><xsl:if test="D02 =''Y''">&#160;and&#160;</xsl:if></span><span class="highlight"><xsl:if test="D03 =''Y''">Citizenship and/or Identity</xsl:if></span>. We need a little more information to finish your application. Addition of few words like 7 o'clock, employees' or employ's and child's and 'xyz and 'hello'</p>contact number for inquiry = '478965152' and email id = '[email protected]'<xsl:template match="num[ . = 3 or . = 5]"/></xsl:stylesheet><xsl:if test="contains($search, ''Web Developer'') and (contains($expSearch, ''Computer'') or contains($expSearch, ''Information'') or contains($expSearch, ''Web''))"><xsl:if test="((node/ABC!='''') and (normalize-space(node/DEF)='''') and (normalize-space(node/GHI)=''''))"> just a dummy sample.</xsl:if> 
+0

Für etwas Regex verwandt, das so einfach ist, müssen Sie keine These als Beispiel veröffentlichen. Zeigen Sie vor und nach dem gewünschten String, dem verwendeten Regex und den Strings, die Ihnen Probleme bereiten.Es ist immer besser, zunächst eine Regex zu erstellen, die alles tut, was Sie brauchen. Weil Sie das als Referenz verwenden müssen, wenn Sie versuchen, die Regex in Teile zu zerlegen, was den gesamten Umfang verändert. – sln

+0

@Sanjay könnten Sie ein Ein-Wort-Beispiel vielleicht hinzufügen (zB 'computer' vs' '' computer''' oder etwas? –

+0

Ich habe hinzugefügt Abschnitt, um das Problem in einfachen Begriff zu erarbeiten. –

Antwort

1

Ich nehme an, dass es in Ordnung ist, zwei verschiedene Regex-Ersetzungen zu verwenden, einen in einer Schleife.
(Das "g" Modifikator hilft nicht.)

Hier kann das Konzept für Ihre usecase für Java-Implementierung ist:

  • zuerst alle '' von '''',
    einmal ersetzen, sondern global
  • ersetzen (<xsl([^>']|'')+)'(([^>']|[^>']+'')+)'(([^'>])+) von \1''\3''\5, nicht global, aber in einer Schleife, bis es nichts mehr ersetzt
  • wenn das funktioniert, ist der nächste Schritt, es zu machen nehmen xsl und auch XSL und erlauben auch den optionalen Leerzeichen gewünschten
    (<\\s*(xsl|XSL)([^>']|'')+)'(([^>']|[^>']+'')+)'(([^'>])+)

Ich bin keinen Javaman (respektvolles Wortspiel beabsichtigt), so kann ich nicht einen Demonstrator in Java bieten.
Hier ist ein Demonstrator (du brauchst ihn nicht, nur um zu zeigen, was ich getestet habe) in sed.
Es implementiert das obige Konzept und hat die gewünschte Ausgabe für den angegebenen Beispieleingang.

bash-3.1$ sed -En "1{s/''/''''/g;:a;s/(<xsl([^>']|'')+)'(([^>']|[^>']+'')+)'(([^'>])+)/\1''\3''\5/;ta;p};" input.txt > output.txt 

Der Haupttrick ist, nach etwas zu suchen, das NICHT in einem bereits erfolgreich ersetzten Teil vorkommt und dann ersetzt, während es erfolgreich war.
Der sekundäre Trick ist, zuerst alles zu ersetzen, was ersetzt werden muss, aber sieht bereits ersetzt ('' ->'''').

Hinweis:
Während Java und Sed potenziell unterschiedliche Regex-Aromen haben, sehe ich nichts, was offensichtlich Konflikte verursacht, wenn Sie Ihre Regex mit meiner vergleichen. Meins enthält nicht einmal \s \d \w oder ähnliches.
Sie müssen möglicherweise Ihre $1''$3''$5 anstelle meiner \1''\3''\5 verwenden.

0

Dies ist unmöglich, wenn Sie erlauben beliebige Verschachtelung von Elementen innerhalb der <xsl> </> Tags. Siehe RegEx match open tags except XHTML self-contained tags.

Sie könnten eine Regex für diesen speziellen Fall entwerfen, aber nicht für jeden möglichen Fall.

+0

Ich muss kein Parsing machen Nur zum Erstellen von DBCR für XSLT brauche ich Regex Es hat nur eine einfache Regel: I muss '' 'durch' '' 'in allen Zustand prüfen. und alle anderen Orte bleibend werde ich' '' durch ''||' '' ersetzen. Das ist es. Wenn Sie meinen Code sehen, dann werden Sie finde, dass ich fast das richtige Ergebnis bekomme, nur an den Stellen, an denen die Zustandsprüfung "und" oder "ODER" hat, ist mein Ergebnis nicht wie erwartet. –

0

Wenn Sie nur die TAGS analysieren, funktioniert dies.
Wenn Sie versuchen, HTML-Closure zu interpretieren, kann es nicht mit Java
Regex durchgeführt werden.

Die Grundidee ist, dass Sie nicht nur XSL-Tags analysieren können. Alle Tags müssen geparst werden
, um die Match-Position voranzutreiben und vorbei an Tags, die HTML verstecken können.

Also müssen alle Tags analysiert werden.
In der Regex unten, Capture Group 2 enthält die xsl-Tags, die Sie finden möchten.

Alle Tags werden übereinstimmen. Sie können diese ignorieren und suchen Sie nur, wenn
Fanggruppe 2 Länge hat. Das ist derjenige, den du manipulieren willst.

Was wir tun, ist ein Alle mit einem Rückruf ersetzen.

Innerhalb des Rückrufs:

  • Wenn Capture-Gruppe 2 nicht überein (das heißt keine Länge)
    nur den Inhalt der Capture-Gruppe 0 zurück (das Spiel).
    Dies ersetzt nur mit was zusammenpasst. Dies sind die anderen Tags.

  • Wenn Capture-Gruppe 2 tat Spiel Kopiergruppe 2 in einen String
    und führen Sie eine andere Regex auf diesem String (es Inhalt) ersetzen.
    Das wäre eine globale Suche (?<!')'(?!') Ersetzen ''.
    Geben Sie diese Zeichenfolge als Ersatz im Callback zurück.

Das ist alles da ist zu ihm.

Halten Sie sich jetzt selbst fest.
Dies ist die Regex.

(Du kann diesen Fall unempfindlich machen, wenn Sie wollen)

"<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\\s+(?>\"[\\S\\s]*?\"|'[\\S\\s]*?'|(?:(?!/>)[^>])?)+)?\\s*>)[\\S\\s]*?</\\1\\s*(?=>))|(?:/?[\\w:]+\\s*/?)|(xsl:[\\w:-]*\\s+(?:\"[\\S\\s]*?\"|'[\\S\\s]*?'|[^>]?)+\\s*/?)|(?:[\\w:]+\\s+(?:\"[\\S\\s]*?\"|'[\\S\\s]*?'|[^>]?)+\\s*/?)|\\?[\\S\\s]*?\\?|(?:!(?:(?:DOCTYPE[\\S\\s]*?)|(?:\\[CDATA\\[[\\S\\s]*?\\]\\])|(?:--[\\S\\s]*?--)|(?:ATTLIST[\\S\\s]*?)|(?:ENTITY[\\S\\s]*?)|(?:ELEMENT[\\S\\s]*?))))>"

Expanded
< 
(?: 
     (?: 
      (?: 
       # Invisible content; end tag req'd 
       (       # (1 start) 
        script 
        | style 
        #| head 
        | object 
        | embed 
        | applet 
        | noframes 
        | noscript 
        | noembed 
       )        # (1 end) 
       (?: 
        \s+ 
        (?> 
          " [\S\s]*? " 
         | ' [\S\s]*? ' 
         | (?: 
           (?! />) 
           [^>] 
         )? 
        )+ 
       )? 
       \s* > 
      ) 

      [\S\s]*? </ \1 \s* 
      (?= >) 
    ) 

    | (?: /? [\w:]+ \s* /?) 

    | (       # (2 start), The xsl: we want to find 
      xsl: [\w:-]* 
      \s+ 
      (?: 
       " [\S\s]*? " 
      | ' [\S\s]*? ' 
      | [^>]? 
      )+ 
      \s* /? 
    )        # (2 end) 
    | (?: 
      [\w:]+ 
      \s+ 
      (?: 
       " [\S\s]*? " 
      | ' [\S\s]*? ' 
      | [^>]? 
      )+ 
      \s* /? 
    ) 
    | \? [\S\s]*? \? 
    | (?: 
      ! 
      (?: 
       (?: DOCTYPE [\S\s]*?) 
      | (?: \[CDATA\[ [\S\s]*? \]\]) 
      | (?: -- [\S\s]*? --) 
      | (?: ATTLIST [\S\s]*?) 
      | (?: ENTITY [\S\s]*?) 
      | (?: ELEMENT [\S\s]*?) 
      ) 
    ) 
) 
> 

Abschließender Hinweis - Um zu sehen, wie effektiv und schnell dieser regex ist,
get ein großer HTML-Quellcode. Führen Sie einen globalen Suchvorgang aus und ersetzen Sie ihn durch ''.
Sie werden jetzt den gesamten Inhalt sehen, völlig HTML entfernt.