我需要在來自資料庫的文本中進行多重替換,然后再將其顯示給用戶。
我的例子是針對最可能在CRM上找到的資料,其輸出是用于網路的HTML,但這個問題可以推廣到任何其他文本替換需求。這個問題對于任何編程語言都是通用的。在我的案例中,我使用的是PHP,但這更像是一個演算法問題,而不是一個PHP問題。
問題是
。我在下面寫的3個例子中的每一個都是通過正則運算式超級容易做到的。但是,即使我做了多步驟的替換,將它們組合在一起也不是那么直接。它們會產生干擾。
問題
是否有一個設計模式來做多個相互干擾的文本替換?替換的例子#1。IDs。
我們用ID來作業。ID是sha-1摘要。ID是通用的,可以代表公司中的任何物體,從一個用戶到一個機場,從一張發票到一輛汽車。
因此,在資料庫中,我們可以找到要顯示給用戶的這段文字:
用戶d19210ac35dfc63bdaa2e495e17abe5fc9535f02支付50歐元
在付款377b03b0b4e92502737eca2345e5bdadb1262230。我們發送了
一封電子郵件a49c6737f80eadea0eb16f4c8e148f1c82e05c10來確認。
我們希望所有的ID都被翻譯成鏈接,以便用戶觀看它的資訊可以點擊。有一個一般的URL用于解碼ID。讓我們假設它是http://example.com/id/xxx
轉換后的文本將是這樣的:
User <a href="http://example.com/id/d19210ac35dfc63bdaa2e495e17abe5fc9535f02">d19210ac35dfc63bdaa2e495e17abe5fc9535f02</a> paid 50 EUR
in the payment <a href="http://example.com/id/377b03b0b4e92502737eca2345e5bdadb1262230">377b03b0b4e92502737eca2345e5bdadb1262230</a>. 我們發送了
一封電子郵件<a href="http://example.com/id/a49c6737f80eadea0eb16f4c8e148f1c82e05c10">a49c6737f80eadea0eb16f4c8e148f1c82e05c10</a> 以確認
替換的例子#2。鏈接
我們希望任何與URI相似的東西都可以被點擊。讓我們只關注http和https協議,而忘掉其他的協議。
如果我們在資料庫中找到這個:
。我們的網站是http://mary.example.com,而您所要求的資訊
你所要求的資訊在這個頁面上 http://mary.example.com/info.php
將被轉換為:
我們的網站是<a href="http://mary.example.com">http://mary.example.com</a>和你所要求的資訊是在這個頁面上。
你所要求的資訊是在這個頁面 <a href="http://mary.example.com/info.php">http://mary.example.com/info.php</a>
替換的例子#3。HTML
當原始文本包含HTML時,它不能被發送raw,因為它將被解釋。我們要把<和>字符改為轉義形式的<和>。HTML-5的翻譯表也包含了要轉換為&符號的&,這也影響了電子郵件的Message Ids的翻譯,比如說
例如,如果我們在資料庫中找到這個:
我們需要將<code>標簽的CSS改為純綠色。
在Message-ID: <[email protected]> 今天早上發送給John&Partners。
由此產生的替換將是:
我們需要將<code>標簽的CSS改為純綠色。
在Message-ID: <[email protected]>中發送給John&Partners,今天早上。
好吧... 但是......組合?
到這里為止,每一個變化 "本身 "都是超級簡單的。
但是,當我們組合東西時,我們希望它們對用戶來說仍然是 "自然 "的。讓我們假設原始文本包含HTML。而其中一個標簽是一個<a>標簽。我們仍然希望看到完整的標簽被 "顯示 "出來,并且HREF可以被點擊。如果它是一個鏈接的話,還可以看到錨點的文本。
組合樣本。##2(注入鏈接)然后#3(扁平化HTML)
。假設我們在資料庫中有這樣的內容:
如果我們首先應用#2來轉換鏈接,然后應用#3來編碼HTML,我們將得到: 應用規則#2來轉換鏈接,然后應用#3來編碼HTML。
在原始鏈接上應用規則#2(注入鏈接), 這顯然是一個破碎的HTML,沒有任何意義,但是,此外,在#2的輸出上應用規則#3(扁平化HTML),我們會有: 這又是破損的HTML的單純平面HTML表示,不能點擊。錯誤的輸出。無論是#2還是#3都沒有得到滿足。
如果我先應用規則 #3 來 "解碼所有 HTML",然后再應用規則 #2 來 "注入鏈接 HTML",就會發生這樣的情況:貼上這樣的內容。
把這個<a class="dark" href="http://example.com/data.xml">下載</a>粘貼到你的文本編輯器。
http://example.com/data.xml被檢測到并被<a href="http://example.com/data.xml">http://example.com/data.xml</a>/code>把這個<a class="dark" href="<a href="http://example.com/data.xml">http://example.com/data.xml</a>">下載</a>粘貼到你的文本編輯器。
把這個<a class="dark" href="<a href="http://example.com/data.xml">http://example.com/data.xml</a>">Download</a>粘貼到你的文本編輯器。
相反的組合。首先是#3(扁平化HTML),然后是#2(注入鏈接)
。
把這個<a class="dark" href="http://example.com/data.xml">下載</a>粘貼到你的文本編輯器中。
應用#3(扁平化HTML)的結果
把這個<a class="dark" href="http://example.com/data.xml">Download</a>粘貼到你的文本編輯器。
然后我們應用第2條規則(注入鏈接),它似乎是有效的:
把這個<a class="dark" href="<a href="http://example.com/data.xml">http://example.com/data.xml</a>">下載</a>粘貼到你的文本編輯器。
這樣做是因為"不是一個有效的URL字符,并檢測到http://example.com/data.xml作為確切的URL限制。
但是......如果原始文本的鏈接文本內也有一個鏈接呢?這是一個非常常見的情況。像這樣的原文:
把這個<a class="dark" href="http://example.com/data.xml">http://example.com/data.xml</a>粘貼到你的文本編輯器。
然后應用#2會得到這樣的結果:
將這個<a class="dark" href="http://example.com/data.xml"<http://example.com/data.xml</a> 粘貼到你的文本編輯器中。
在這里我們有一個問題
。由于所有的&、;和/都是有效的URL字符,URL決議器會發現這個。http://example.com/data.xml</a>作為URL,而不是在.xml點結束。
這將導致這個錯誤的輸出:
把這個<a class="dark" href="<a href="http://example.com/data.xml">http://example.com/data.xml</a>"<<a href="http://example.com/data.xml</a>">http://example.com/data.xml</a><;/a>;粘貼到文字編輯器。
因此http://example.com/data.xml</a>被<a href="http://example.com/data.xml</a>">http://example.com/data.xml</a></a>取代了,但問題是沒有正確檢測到URL。
讓我們把它與規則#1混合起來
。如果規則 #2 和 #3 在一起處理時是一團糟,想象一下,如果我們將它們與規則 #1 混合,并且我們有一個包含 sha-1 的 URL,就像這個資料庫條目一樣:
如果規則 #2 和 #3 在一起處理時是一團糟,想象一下,如果我們將它們與規則 #1 混合,并且我們有一個包含 sha-1 的 URL,就像這個資料庫條目一樣
將這個<a class="dark" href="http://example.com/id/89019b16ab155ba1c19e1ab9efdb9134c8f9e2b9">http://example.com/id/89019b16ab155ba1c19e1ab9efdb9134c8f9e2b9</a>粘貼到你的文本編輯器。
你能想象嗎?
標記器?
我曾想過要創建一個語法標記器。但我覺得這是個過度的做法。
是否有一個設計方案?
是否有一個設計模式
?
我想知道在進行多文本替換時,是否有一種設計模式可以閱讀和研究,它是如何被呼叫的,以及它在哪里被記錄。
如果沒有任何模式......那么......建立一個語法標記器是唯一的解決方案嗎?
我覺得肯定有一個更簡單的方法來做這件事。我是否真的必須在語法樹中對文本進行標記,然后通過遍歷該樹來重新渲染?
uj5u.com熱心網友回復:
這個設計模式就是你已經拒絕的那個模式,即從左到右的標記化。當然,這在那些有代碼生成器產生詞法掃描器的語言中更容易做到。
沒有必要進行決議或建立語法樹。一個標記的線性序列就足夠了。實際上,掃描器成為一個轉換器。每個標記要么不加改動地通過,要么立即用所需的翻譯來替換。
標記器也不需要特別復雜。你目前擁有的三種正則運算式可以被使用,并與代表任何其他字符的第四種標記型別相結合。重要的是,在每個點上都要嘗試所有的模式,選擇一個,執行指定的替換,并在匹配后恢復掃描。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/315102.html
標籤:
