2017-08-31 85 views
2

我通過this鏈接將sgml內容轉換爲xml內容。 使用sgmlString.replaceAll("<(([^<>]+?)>)([^<>]+?)(?=<(?!\\1))", "<$1$3</$2>");正則表達式我幾乎接近預期結果,但對於以下文件,當有多個並行標記沒有關閉時,它將僅關閉最後一個標記的標記。將SGML轉換爲XML的正則表達式

輸入:

<SEC-HEADER>0001104659-17-052330.hdr.sgml : 20170817 
    <ACCEPTANCE-DATETIME>20170817060417 
    <ACCESSION-NUMBER>0001104659-17-052330 
    <TYPE>8-K 
    <PUBLIC-DOCUMENT-COUNT>4 
    <PERIOD>20170816 
    <ITEMS>7.01 
    <ITEMS>8.16 
    <FILING-DATE>20170817 
    <DATE-OF-FILING-DATE-CHANGE>20170817 
    <FILER> 
     bye bye see you! 
    </FILER> 
</SEC-HEADER> 

輸出(注:僅ITEMS標籤的一個關閉和FILER兩個倒閉,預計不會)

<SEC-HEADER>0001104659-17-052330.hdr.sgml : 20170817 
    <ACCEPTANCE-DATETIME>20170817060417</ACCEPTANCE-DATETIME> 
    <ACCESSION-NUMBER>0001104659-17-052330</ACCESSION-NUMBER> 
    <TYPE>8-K</TYPE> 
    <PUBLIC-DOCUMENT-COUNT>4</PUBLIC-DOCUMENT-COUNT> 
    <PERIOD>20170816</PERIOD> 
    <ITEMS>7.01<ITEMS>8.16</ITEMS> 
    <FILING-DATE>20170817</FILING-DATE> 
    <DATE-OF-FILING-DATE-CHANGE>20170817</DATE-OF-FILING-DATE-CHANGE> 
    <FILER>bye bye see you!</FILER></FILER> 
</SEC-HEADER> 
預計:
<SEC-HEADER>0001104659-17-052330.hdr.sgml : 20170817 
     <ACCEPTANCE-DATETIME>20170817060417</ACCEPTANCE-DATETIME> 
     <ACCESSION-NUMBER>0001104659-17-052330</ACCESSION-NUMBER> 
     <TYPE>8-K</TYPE> 
     <PUBLIC-DOCUMENT-COUNT>4</PUBLIC-DOCUMENT-COUNT> 
     <PERIOD>20170816</PERIOD> 
     <ITEMS>7.01</ITEMS> 
     <ITEMS>8.16</ITEMS> 
     <FILING-DATE>20170817</FILING-DATE> 
     <DATE-OF-FILING-DATE-CHANGE>20170817</DATE-OF-FILING-DATE-CHANGE> 
     <FILER>bye bye see you!</FILER> 
    </SEC-HEADER> 

我需要你的友好建議/指導,對下列查詢:

  1. 是否使用正則表達式用於獲取結束標記,使其在XML格式的好方法,因爲我讀正則表達式很慢?
  2. 我有相當繁重的文件處理(最多18000行/標籤),有沒有更好的方法來實現它?
  3. 如何在正則表達式改變獲得期望的結果(我真的弱EL)
+1

我可以建議你看看使用XSLT,從我的理解來看,它可能非常適合這種XML轉換問題?我認爲在這裏使用正則表達式會引發問題,尤其是嵌套標記。 –

+0

我不知道XSLT以及如何使用它。您能否提供一些指南/工作示例的鏈接或其他可供參考的鏈接。感謝您的快速回復。 –

+0

@TimBiegeleisen對於任何尚未完成的任何事情,XSLT不會失敗嗎? – Yunnosch

回答

0

我在Perl的解決方案。 它基於<SEC-HEADER>的特殊處理,併入它。

Perl代碼:

use strict; 
use warnings; 

my $Input =''; 
while(<>) 
{ 
    $Input.=$_; 
} 

$Input =~ s/<((?!SEC-HEADER)([^\/<>]+?)>)([^<>]+?)(\s*?)(?=<[^\/])/<$1$3<\/$2>$4/g; 
print $Input; 

爲了它(我不能測試並有猜測它的語法)翻譯成你的工具,我建議嘗試:

sgmlString.replaceAll("<((?!SEC-HEADER)([^\/<>]+?)>)([^<>]+?)(\s*?)(?=<[^\/])", "<$1$3<\/$2>$4"); 

對不起,你將不得不自己拋光一些特定於工具的錯誤,可能是嘗試錯誤。
與我的Perl版本我得到了以下輸出,我希望是足夠接近,它只是不吃<FILER>內的空白。

輸出:

<SEC-HEADER>0001104659-17-052330.hdr.sgml : 20170817 
    <ACCEPTANCE-DATETIME>20170817060417</ACCEPTANCE-DATETIME> 
    <ACCESSION-NUMBER>0001104659-17-052330</ACCESSION-NUMBER> 
    <TYPE>8-K</TYPE> 
    <PUBLIC-DOCUMENT-COUNT>4</PUBLIC-DOCUMENT-COUNT> 
    <PERIOD>20170816</PERIOD> 
    <ITEMS>7.01</ITEMS> 
    <ITEMS>8.16</ITEMS> 
    <FILING-DATE>20170817</FILING-DATE> 
    <DATE-OF-FILING-DATE-CHANGE>20170817</DATE-OF-FILING-DATE-CHANGE> 
    <FILER> 
     bye bye see you! 
    </FILER> 
</SEC-HEADER> 

詳情:

  • 使用負匹配與實際找到的標記名稱,而不是\1
  • /,而不是\
  • 在一開始,期望非/
  • 忽略特殊標籤名稱SEC-HEADER,爲您隱允許
  • 捕捉一些空白,並用它來獲得縮進和換行權

如果你想空白吃掉了,這裏是一個(perl的)替換到做到這一點:

$Input =~ s/<(?!\/)([^<>]+)>\s*([^<>]+[^\s<>])\s*<\/\1>/<$1>$2<\/$1>/g; 

孰料版本爲您的工具
(再次,對不起小錯誤,請擦亮自己他們):

sgmlString.replaceAll("<(?!\/)([^<>]+)>\s*([^<>]+[^\s<>])\s*<\/\1>", "<$1>$2<\/$1>"); 

輸出(第一碼之後施加):

<SEC-HEADER>0001104659-17-052330.hdr.sgml : 20170817 
    <ACCEPTANCE-DATETIME>20170817060417</ACCEPTANCE-DATETIME> 
    <ACCESSION-NUMBER>0001104659-17-052330</ACCESSION-NUMBER> 
    <TYPE>8-K</TYPE> 
    <PUBLIC-DOCUMENT-COUNT>4</PUBLIC-DOCUMENT-COUNT> 
    <PERIOD>20170816</PERIOD> 
    <ITEMS>7.01</ITEMS> 
    <ITEMS>8.16</ITEMS> 
    <FILING-DATE>20170817</FILING-DATE> 
    <DATE-OF-FILING-DATE-CHANGE>20170817</DATE-OF-FILING-DATE-CHANGE> 
    <FILER>bye bye see you!</FILER> 
</SEC-HEADER> 
1

雖然它可能用於SGML在手使用正則表達式匹配的工作,一般地/替換爲SGML轉換成XML可怕的方法,因爲SGML有標籤省略/標籤推斷,屬性名稱和值的省略(如HTML)以及SGML的XML配置文件中沒有的其他簡短形式和功能。

但是,有專門的osx SGML到XML轉換程序,我可以完全推薦它。其來源可從http://openjade.sourceforge.net/獲得。如果你使用的是Debian/Ubuntu,你可以通過sudo apt-get install opensp進行安裝,如果你使用的是Mac OS(你必須首先安裝MacPorts),通過sudo port install opensp(不知道MacBrew的等價物)。

相關問題