">" Eşleştirmek için düzenli ifade, "<", "&"

7 Cevap php

Ben PHP PCRE kütüphanesi kullanarak normal bir ifade yazmak çalışıyorum.

Ben sadece &, > ve herhangi bir XML düğümü değil etiket beyan kendilerini dize parçası içinde var < karakter eşleştirmek için bir regex gerekir.

Input XML:

<pnode>
  <cnode>This string contains > and < and & chars.</cnode>
</pnode>

Fikir bir arama olduğunu ve bu karakter değiştirmek ve XML kişiler eşdeğerleri çevirebiliriz.

Ben kuruluşlara tüm XML dönüştürmek için ise XML bu gibi görünecektir:

Entire XML converted to entities

&lt;pnode&gt;
  &lt;cnode&gt;This string contains &gt; and &lt; and &amp; chars.&lt;/cnode&gt;
&lt;/pnode&gt;

Ben bu gibi bakmak gerekir:

Correct XML

<pnode>
  <cnode>This string contains &gt; and &lt and &amp; chars.</cnode>
</pnode>

Ben göz-ahaead kullanarak bu karakterleri eşleştirmek için normal bir ifade yazmak için denedim ama ben bu işe almak için yeterli bilmiyorum. (Şu anda sadece> semboller maç teşebbüs) benim girişimi:

/>(?=[^<]*<)/g

Just to make it clear the XML I'm trying to fix comes from a 3rd party and they seem unable to fix it their end hence my attempt to fix it.

7 Cevap

Sonunda ben PHP Tidy kütüphane kullanımı için tercih ettik. Ben kullanılan kod aşağıda gösterilmiştir:

  // Specify configuration
  $config = array(
    'input-xml'  => true,
    'show-warnings' => false,
    'numeric-entities' => true,
    'output-xml' => true);

  $tidy = new tidy();
  $tidy->parseFile('feed.xml', $config, 'latin1');
  $tidy->cleanRepair()

Bu mükemmel tüm kodlama hataları düzelterek ve XML kişilere geçersiz karakterler dönüştürmek çalışır.

Çöp dışarı, çöp klasik bir örneğidir. Gerçek çözüm kırık XML ihracatçısı düzeltmek için, ama belli ki bu sorunun kapsamı dışında bulunuyor. Elle htmlentites() içeriğine, sonra tekrar XML etiketleri koymak çalıştırmak XML, ayrıştırmak olabilir gibi geliyor.

Ben sadece mümkün değil makul eminim. Sen iç içe izler şey gerekir, ve yuvalama izlemek için normal bir ifade almak için hiçbir yolu yoktur. (Muhtemelen bir RE kullanabilirsiniz zaman) ilk metni düzeltmek veya bir XML ayrıştırıcı gibi en azından belli belirsiz bir şeyi kullanmak, özellikle etiketleri iç içe nasıl takip ölçüde için seçimlerdir.

Bu olmadan, sadece bir şey gerçekten bir etiket olup olmadığı hakkında tahmin edebilirsiniz - XML ​​bu karakterler olsa da kaçtı, bu talepleri bir sebebi var. Örneğin, gibi bir şey verilmiştir:

    <tag>Text containing < and > characters</tag>

sen ve ben muhtemelen sonucu olması gerektiğini tahmin edebilirsiniz: ...containing &lt; and &gt;... ama XML spesifikasyonu allows ekstra boşluk, yani resmen "" tedavi edilmelidir eminim bir etiket olarak. Sen, sanırım, bir un-uyumlu etiketi gerçekten bir etiket olması amaçlanmıştır değildir benziyor şey varsayalım, ama o da bazı işler almaya gidiyor.

Bu XML parçası haline çalışır önce metni kesmek mümkün olurdu? Önleme birkaç ons tedavi değerinde kilo olabilir.

Bu 'işareti için bunu yapmak gerekir:

/(\s+)(&)(\s+)/gim

Bu, her iki tarafta da boşluk karakterleri varsa sadece bu karakterler arıyor demektir.

Sadece yedek ifadesi "$ 3 $ 1 $ 2Amp" olduğundan emin olun;

Diğerleri sağda onların yerine ifadeler ile, bu böyle gider

/(\s+)(>)(\s+)/gim   "$1&gt;$2"
/(\s+)(<)(\s+)/gim   "$1&lt;$2"

Başkaları tarafından belirtildiği gibi, düzenli ifadeler hiyerarşik veri ile iyi yapmak değildir. Veri hatalı biçimlendirilmiş yanında eğer, size doğru alırsınız garanti edemez. Düşünün:

<xml>
    <tag>Something<br/>Something Else</tag>
</xml>

<br/> okumak gerekiyordu olduğunu &lt;br/&gt;? Bu geçerli şekilde XML biçimli çünkü bilmek için hiçbir yolu yok.

Eğer XML ağacı dahil etmek isteyen rasgele veri varsa, bunun yerine bir <![CDATA[ ... ]]> bloğunu kullanmayı düşünün. Bir metin düğümü olarak aynı tedavi ve kaçmak zorunda değilsiniz tek şey karakter dizisi ]]> olduğunu bulunuyor.

Ne var XML, tabii ki yoktur. XML, karakterleri '<' ve '&' metin içinde (çıkmamış) oluşabilir: sadece bir yorum içinde, CDATA bölümü veya işleme talimatıdır. Aslında, '>' ']]>' dizesinin bir parçası olarak dışında, metin oluşabilir. Iyi biçimlendirilmiş XML, literal '<' ve '&' karakterleri biçimlendirme başlangıç ​​sinyali: '<' Bir başlangıç ​​etiketi, bitiş etiketi veya boş eleman etiketi başlangıcı sinyalleri, ve '&' bir varlık referans başlangıcı sinyalleri. Bu iki durumda da, bir sonraki karakter boşluk olmayabilir. Yani ROBUSTO telkini gibi bir RE kullanarak tüm bu oluşumları bulur. Ayrıca, '<<', '<\' gibi köşe durumlarda yakalamak gerekir, ya da '& <' olabilir. Bu durumda size girişi ayrıştırmak için denemek gerekmez, bir RE iyi çalışır.

If the source contains strings like '<something ' where 'something' matches the production for a Name:

Name ::= NameStartChar (NameChar)*

Then you have more of a problem. You are going to have to (try to) parse your input as if it were real XML, and detect the error cases of malformed Names, non-matching start & end tags, malformed attributes, and undefined entity references (to name a few). Unfortunately the error condition isn't guaranteed to happen at the location of the error.

Yapabileceğiniz en iyi şey hata% 90 yakalamak ve el kalanını düzeltmek için bir RE kullanmak olabilir. Eğer bir '<' için bakmak gerekir veya '&' Bir AdBaşlKark başka bir şey tarafından takip