2016-07-20 74 views
2

大家好,我的問題很簡單的一組:比賽多次只在單一的正則表達式

我想匹配,只有當他們在與PCRE正則表達式一個<figcaption>的一篇文章中所有可能的井號標籤。 E.g:

<figcaption>blah blah #hashtag1, #hashtag2</figcaption> 

我這裏https://regex101.com/r/aL9vS8/1做出了嘗試,並去掉最後?將從#hashtag1捕獲更改爲#hashtag2,但不能同時獲得。

我甚至不確定它是可行的在一個單一的正則表達式在PHP

任何想法來幫助我? :)

如果沒有辦法在一個單一的正則表達式(真的嗎?即使使用遞歸(?R)??:p),請建議最有效的方式可能性能明智。

謝謝!

[編輯]

如果沒有辦法,我的PHP的下一個想法是:

  1. 匹配每一個figcaption與preg_replace_callback
  2. 在回調比賽#hashtag每個實例。

我可以就此瞭解你的意見嗎?有沒有更好的辦法?我的文章不是很長。

+0

figcaption是一個HTML標籤。您可以使用JS來獲得figcaption文本,然後開始尋找使用正則表達式的井號標籤的搜索。 – rmondesilva

+1

的可能的複製(HTTP [如何捕獲在JavaScript正則表達式組的任意號碼?]://計算器。com/questions/3537878/how-to-capture-an-arbitrary-number-of-groups-in-javascript-regexp) –

+0

這裏的要點是沒有必要匹配「任意數量的組」,這個問題是不是上述的一個騙局。實際上,JS標籤應該被刪除,共享的嘗試是一個PCRE正則表達式。 –

回答

2

請推薦最有效的方式表現明智

最可靠的方法來匹配一些分隔符與PCRE正則表達式之間的一些文字是通過使用自定義的邊界與\G operator。但是,尾部邊界是多字符字符串,要匹配除</figcaption>之外的任何文本,您需要tempered greedy token。由於此令牌非常耗費資源,因此必須展開。

這是給你的任務快速,可靠PCRE正則表達式:

(?:<figcaption|(?!^)\G)[^<#]*(?:(?:<(?!\/figcaption>)|#\B)[^<#]*)*\K#\w+ 

regex demo

詳細

  • (?:<figcaption|(?!^)\G) - 匹配<figcaption或前結束成功搭配
    更多細節:
    (?:<figcaption|(?!^)\G)非捕獲器,它只有羣組(?:...)),而不是跟蹤與此組什麼匹配(即沒有值保存在匹配2倍的替代品(|是交替操作)的堆疊組,因爲不會創建堆棧):1)文字文本<figcaption或2)(?!^)\G - 以前的成功匹配後的位置(注意:\G也匹配字符串的開始,因此,我們必須添加負先行(?!^)排除行爲)。
  • [^<#]* - 比<其他0+字符和#
  • (?:(?:<(?!\/figcaption>)|#\B)[^<#]*)* - 的0+序列:
    • (?:<(?!\/figcaption>)|#\B) - 一個<後面沒有與/figcaption>#或沒有遵循與字炭
    • [^<#]* - 0 +字符除<#
  • \K - 忽略文本到目前爲止匹配
  • #\w+ - #和1+字字符

更細節

逃逸序列\K導致任何公關明顯匹配的字符不包含在最終的匹配序列中。例如,模式:

foo\Kbar 

比賽foobar,但報告說,它匹配了bar。該功能類似於後向斷言。

  • (?:(?:<(?!\/figcaption>)|#\B)[^<#]*)*:在這裏,我們有一個外非捕獲組(?:...)*使匹配子模式零次或多次的序列(能量詞*設置爲僅一個分組,如果我們需要重複一個序列的子模式)與內非捕獲組(?:<(?!\/figcaption>)|#\B)[^<#]*只是一個收縮方式較長<(?!\/figcaption>)[^<#]*|#\B[^<#]*(只是第2層不同的替代<(?!\/figcaption>)#\B一個共同的「後綴」 [^<#]*之前
  • 包裝在一個標籤:只使用preg_replace<span class="highlight">$0</span>替換模式:

代碼:

$re = '~(?:<figcaption|(?!^)\G)[^<#]*(?:(?:<(?!\/figcaption>)|#\B)[^<#]*)*\K#\w+~'; 
$str = "<figcaption>blah # blah #hashtag1, #hashtag2</figcaption> #ee <figcaption>#ddddd"; 
$subst = "<span class=\"highlight\">$0</span>"; 
$result = preg_replace($re, $subst, $str); 
echo $result; 

PHP IDEONE demo

+0

Waw非常感謝!這聽起來很棒,工作...你能幫我更好地瞭解你的正則表達式一步一步來幫助我捕獲後來更換的hashtag? – antoni

+0

你不需要*捕獲*標籤,它是*匹配*這種方式。即使標籤被破壞,在打開「

+0

試着對你的例子進行嘗試,我可以做出我想要的替換。完善!真棒!只是希望你可以將你的模式分解成更多的解釋,需要一段時間才能理解haha – antoni