簡體   English   中英

用於捕獲最小組的正則表達式

[英]Regex for capturing smallest group

我正在嘗試捕獲PDF 頁面對象的ID,如下所示:

4 0 obj
<<
/Type /Page /
...
>>
endobj

ID是' ID 0 obj'。 問題是我的文件有多個對象,因此以下模式從第一個對象聲明捕獲到Page對象的第一個實例:

preg_match_all("/([0-9]+) 0 obj.+?\/Page[ \n]*?\//s", $input_lines, output_array);

以下是我的文件示例,如果您想嘗試一下,您會看到包含單詞“Page”的多個對象:

%PDF-1.3
%¦¦¦¦

1 0 obj
<<
/Type /Catalog /AcroForm << /Fields [12 0 R 13 0 R] /NeedAppearances false  /SigFlags 3 /Version /1.7 /Pages 3 0 R /Names << >> /ViewerPreferences << /Direction /L2R >> /PageLayout /SinglePage /PageMode /UseNone /OpenAction [0 0 R /FitH null] /DR << /Font << /F1 14 0 R >> >> /DA (/F1 0 Tf 0 g) /Q 0 >> /Perms << /DocMDP 11 0 R >>
/Outlines 2 0 R
/Pages 3 0 R
>>
endobj

2 0 obj
<<
/Type /Outlines
/Count 0
>>
endobj

3 0 obj
<<
/Type /Pages
/Count 2
/Kids [ 4 0 R 6 0 R ]
>>
endobj

4 0 obj
<<
/Type /Page
/Parent 3 0 R
/Resources <<
/Font <<
/F1 9 0 R
>>
/ProcSet 8 0 R
>>
/MediaBox [0 0 612.0000 792.0000]
/Contents 5 0 R
>>
endobj

5 0 obj
<< /Length 1074 >>
stream
2 J
BT
0 0 0 rg
/F1 0027 Tf
57.3750 722.2800 Td
( A Simple PDF File ) Tj
ET
BT
/F1 0010 Tf

我應該改變什么才不讓它變得貪婪?

編輯:澄清

  • 我忘了提到我需要捕獲所有的Page對象ID。
  • 有些人告訴我使用更具體的正則表達式,我不得不說這不是一個關於如何構建對象的正式例子,這也是可能的。 您可以看到空格不是修飾的,並且在頁面'/類型/頁面'標記之前可以有多個標記。

示例:

4 0 obj
<< /UselessTag/Type/Page/
...
>>
endobj
  • 有一些名為PagesPageLayoutSiglePage的標簽,我不想捕捉它們。

你可以用

'~^(\d+) 0 obj(?:(?!^\d+ 0 obj$).)*?\/Type\s*\/Page\s.*?endobj$~sm'

請參閱正則表達式演示

細節

  • ^ - 行錨的開始(因為m修飾符使得^匹配行的開始而不是整個字符串)
  • (\\d+) 0 obj - 1個或更多個數字(捕獲到組1中),然后是空格, 0 ,空格和obj子串
  • (?:(?!^\\d+ 0 obj$).)*? - 一個馴化的貪婪令牌 ,匹配任何不啟動^\\d+ 0 obj$模式的char( . ),盡可能少
  • \\/Type\\s*\\/Page\\s - /Type ,0 + whitespaces(將\\s替換為\\h以僅匹配水平空格), /Page然后是空格
  • .*? - 任何0+字符盡可能少到第一次出現
  • endobj - endobj隨后......
  • $ - 行結束位置。

你可以在特定的量詞中加入一個不合格的問號:

例:

 \(.*\)

火柴:

測試(測試)測試(測試)測試(測試)測試

例:

 \(.*?\)

火柴:

測試(測試)測試(測試)測試(測試)測試

嘗試更具體的正則表達式,因此它不匹配不需要的文本部分。

preg_match_all("/([0-9]+?) 0 obj\n\<\<\n\/Type\s\/Page[ \n]*?\//s", $input_lines, output_array);

證明: https//regex101.com/r/HjyQpS/1

這應該工作:

(\d+) 0 obj[^>]+/Page$

Regex101演示

我不會使用PDF上的正則表達式。 有幾個條件,這種方法將失敗。

  1. 頁面對象位於對象流內(因此打包,很可能是通過Deflate算法)(PDF版本1.5及以上版本允許)
  2. PDF文檔中的增量更新可能導致同一頁面上的雙擊
  3. 標記/頁面不在您要匹配的字典中,而是在間接對象內(從未見過,但理論上可能)。 你有:
 5 0 obj << /Type 6 0 R ....>> endobj 6 0 obj /Page endobj 

注意:您也不能指望每個頁面都按照pdf文檔中的順序編寫,就像您在查看器中看到的那樣。

但是如果你真的必須這樣做,我首先要匹配pdf對象

/([0-9] +)0 obj(。+?)endobj /

並將搜索第二個匹配的字符串

//類型\\ S * \\頁[\\ S>] /

最后>的可選匹配很重要,因為您還需要能夠匹配“/ Type / Page >>”,其中/ Type / Page是pdf字典中的最后一個條目。

使用此正則表達式:

/\d+\s0\sobj.+endobj/smU

請注意,修飾符U使匹配不貪婪。 請參閱此處的匹配示例: https//www.tinywebhut.com/regex/8

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM