2016-07-19 59 views
2

我正在寫一個PHP函數來匹配我的內容中的所有單元。 例如: 我有 「25的NaHCO 3,25 d-葡萄糖,11.6鈉,7硫酸鎂,3.1丙酮酸鈉,2.5氯化鉀,1.25磷酸二氫鈉和0.5氯化鈣」 在我的第一短語爲所有物理/化學/生物單位進行正則表達式匹配?

「 100mg/kg,4kHz至48kHz,40rpm,5分鐘,26cm,95%CI,16年,1.910 J mol-1 K-1,50cm 3 min -1「和許多。

基本思路是捕獲與任何種類的同時單位未來所有值它應該不是隨機匹配「其次是任何字樣號」。

我可以建立一個靜態的正則表達式與各種倒入像

/((?<![\,\-\.\<\=\>\da-z])[\-\+]?\d+(?:[\.\,\/](?=\d)\d+%?)*%?)(?![\-])([\s\x{00A0}\-]*(?:[a-z]{2,}(?:\/?[a-z\-])*(?=[\s\,\.\;\)])|[a-z](?=[\.\,\;]?\s)|A m-[0-9]|C m-[0-9]|F m-1|Gy s-1|H m-1|J K-1(mol-1)?|J kg-1(K-1)?|k?J mol-1(K-1)?|J m-3|N m|N s|Pa|Pa s|V m-1|W|W m-1 K-1|W m-2|W m-2 sr-1|W sr-1|cd sr|mol s-1|kat m-3|kg m s-1|kg m2|kg m2 s-1|kg[\s\/]m-?2|kg m-3|kg\/kg|kg|ci|m[\/]s|m s-[0-9]|[cm]?m-?[0-9](?: (?:k?g|min)-?[0-9])?|mol m-?[0-9]?(?: s-?[0-9])?|rad(?: s-?[0-9])|sr|u\/c|[\x{00B0}\x{00BA}o][FC]|K|\x{00C5}))(?![a-z0-9])/ui 

單位,我可以捕捉到很多,但痛苦是我要補充各單位在我的正則表達式這樣做,即使增加了許多單位後,我可能會錯過許多單位。

是否有任何其他選項來建立動態值的正則表達式?

+0

您能否澄清一下您的每個示例中應該(或不應該)匹配哪些值? –

+0

數值將以小數或小數(33,4.5或66/34)的數字組合形式表示 – Jai

+0

對不起,請讓我更清楚一點 - 請您提供您希望匹配的**實際值**, **給出的例子**。我的解釋是,在第一個例子中,你想*無*匹配;而在第二個例子中,您需要匹配「」100「,」「」4「」,「48」「......。是對的嗎? –

回答

2

第一步是將模式分解爲子模式,這對您的情況尤其有意義。積木應該是:

  • 基本單位:J,K,S,分鐘,年,...
  • 可能前綴的列表:F,P,N,μ,M,C, D,D,K,M,G,T,P ......
  • 可用於形成派生單位的字符列表:。,*,/,^,(,),...

這裏是溶液開始

單位:(([PTGMkDdcmμnpf]?(mol|min|yrs|Hz|rpm|s|K|J|m|g)[\/\^\(\-\+\)0-9]*\s?)+)
未其前面僅有一個值:[\+\-]?\d*\.?\d*e?[\+\-]?\d*\s?(([PTGMkDdcmμnpf]?(%|mol|min|yrs|Hz|rpm|s|K|J|m|g)[\/\^\(\-\+\)0-9]*\s?)+)

第一個應該只解析單位,第二個解析單位和值,忽略沒有跟在單位和單位之後沒有值的數字。

an example of it at work on your example。 我添加了一些您可能需要考慮的更棘手的示例。

但是,請記住,這不會檢查單位的一致性。

您可能想看看GNU Units如何解決這個問題。

它提供單位轉換,並有一個非常廣泛的單位列表(包括貨幣,美國系統和雜項單位,我從來沒有在別處見過)。在源文件中,有一個文件「parse.y」,用於識別單元。

我想你可以從中激發自己,或至少從已建立的單位數據庫中受益。

更新:感謝Nahan Tuggy的更正。Here也是更新版本,甚至有更復雜的例子。

相關問題