2013-11-05 32 views
1

我不確定這是否是一個簡單問題,但至今我一直無法找到答案。我試圖編寫一個正則表達式,將.docx文件拉開,並匹配用<w:ind />標籤替換所有<w:tab />標籤,因爲<w:tab>標籤在轉換爲html時似乎不能正確保存標籤。我正在使用PHP,並且迄今爲止在編寫一個正則表達式時沒有成功,該正則表達式完成我需要的正確操作。我需要匹配組中的所有字符,只要它們不匹配某個詞

問題是,我不能在這裏運行一個簡單的查找和替換功能。我必須刪除<w:tab />標記,並在最近的開啓和關閉<w:rPr></w:rPr>標記內注入<w:ind />標記。

示例XML字符串將是這個樣子:

<w:p w14:paraId="2679030C" w14:textId="4E6FFA99" w:rsidR="00ED4314" w:rsidRPr="00254747" w:rsidRDefault="00ED4314" w:rsidP="00322270"> 
     <w:pPr> 
      <w:pStyle w:val="NoSpacing" /> 
      <w:spacing w:line="480" w:lineRule="auto" /> 
      <w:jc w:val="both" /> 
      <w:rPr> 
       <w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:cs="Times New Roman" /> 
       <w:sz w:val="24" /> 
       <w:szCs w:val="24" /> 
      </w:rPr> 
     </w:pPr> 
     <w:r w:rsidRPr="00254747"> 
      <w:rPr> 
       <w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:cs="Times New Roman" /> 
       <w:sz w:val="24" /> 
       <w:szCs w:val="24" /> 
      </w:rPr> 
      <w:tab /> 
      <w:t>SOME text</w:t> 
     </w:r> 
     <w:r w:rsidR="0003297C"> 
      <w:rPr> 
       <w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:cs="Times New Roman" /> 
       <w:sz w:val="24" /> 
       <w:szCs w:val="24" /> 
      </w:rPr> 
      <w:t>SOME more text</w:t> 
     </w:r> 
     <w:r w:rsidRPr="00254747"> 
      <w:rPr> 
       <w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:cs="Times New Roman" /> 
       <w:sz w:val="24" /> 
       <w:szCs w:val="24" /> 
      </w:rPr> 
      <w:t>EVEN more text</w:t> 
     </w:r> 
    </w:p> 

這樣的<w:tab/>每個實例都需要被移除,然後我會需要向後追蹤到以前<w:rPr>標籤和注入<w:ind />標籤在裏面。

繼承人是我迄今爲止:

$content = preg_replace("/<w:rPr>(.*?)<\/w:rPr>(.*?)<w:tab\/>/", "<w:rPr><w:ind w:firstLine=\"720\"/>$1</w:rPr>$2", $content); 

這個排序的作品,但問題是我認爲搜索是太全局。即使我指定它不貪婪,它返回給我的結果有更多的內容,然後他們應該。任何人都可以提出一個最佳的方法來完善這個?提前致謝!

+1

你可能想看看XML解析器。 – Jerry

回答

1

我覺得你在發現更多標籤—之前,不會將非貪婪與「知道」的正則表達式混淆在一起。如果您意味着</w:rPr><w:tab/>之間不允許標籤,那麼這應該大致工作:

/<w:rPr>(.*?)<\/w:rPr>([^<]*?)<w:tab\/>/ 
         ^^^^ 

這就是所謂的否定字符類,並且所有字符匹配< —因此在找到<w:tab/>之前不會消耗任何其他標籤。


編輯。在響應你的澄清,讓所有標籤除了<w:rPr>找到<w:tab/>之前,你需要使用式斷言,因爲,當你理解正確的,否定的字符類只排除字符,不字符串。

/<w:rPr>(.*?)<\/w:rPr>((?:(?!<w:rPr>).)*?)<w:tab\/>/ 
         ^^^^^^^^^^^^^^^^ 

忽略(?:xyz)如果這是令人困惑—這只是一種方式來獲得括號捕捉—我需要,雖然對量詞*括號。這裏最重要的部分是被稱爲負先行斷言(?!xyz)(順帶也非捕獲組)—它比賽如果展望和不找到「XYZ」 —那麼,是什麼我們上面做的是這樣的:(1)向前看,和(2)如果它不<w:rPr>,然後(3)比賽一個字符,.,以及(4)重複—直到<w:tab/>找到。

+0

這是一個很好的答案!不幸的是,它並沒有完全解決我的問題。標籤和標籤之間可以有多個xml標籤。正因爲如此,我需要更像這樣的東西:/ (。*?)<\/w:rPr>([^ ] *?) /。但是,這不會以我需要的方式工作。有沒有另外一種方法來完成這個? –

+0

查看編輯答案。 –

+0

你是一個真正的正則表達式大師!在我寫這篇文章之前,我研究了前瞻和後向斷言,但是我沒有足夠的理解編寫自己的代碼。你的解釋和例子比我一直遵循的所有教程更有意義。感謝你的清楚!我非常感謝! –

相關問題