2011-03-10 245 views
3

我使用Text::Ngrams來確定字符串中的單詞組合。但是,我需要保留有數字的單詞。我確定$o->{tokenrex}是我需要修改的,但我無法確定它的正確的正則表達式。使用正則表達式匹配包含數字的單詞

原來是qr/([a-zA-Z]+|(\d+(\.\d+)?|\d*\.\d+)([eE][-+]?\d+)?)/;但我想我需要沿此線的東西更多:

qr/([a-zA-Z]+|(?<=\w)(\d+(\.\d+)?|\d*\.\d+)([eE][-+]?\d+)?(?=\w)|(\d+(\.\d+)?|\d*\.\d+)([eE][-+]?\d+)?)/; 

哪些應該,如果我讀正確的正則表達式,匹配任意數量的字母字符,或在其前後具有單詞字符的「數字」或「數字」。除了它將我的「單詞」分解爲單獨的標記。我正在使用的示例詞是「A1X」。

任何協助將是偉大的。

+3

學習如何使用並喜歡'x'正則表達式修飾符,它允許您在正則表達式中使用空格(空格,製表符,換行符)來格式化 – 2011-03-10 16:45:40

+0

@Eric Strom我完全打算;我想在嘗試解釋它做什麼之前先讓它工作:) – 2011-03-10 18:05:01

+0

這就是要點。如果你能看到它的功能,它更容易工作! – ridgerunner 2011-04-03 02:07:06

回答

4

你們都這樣做太複雜了。原始正則表達式僅匹配由字母或數字組成的單詞(整數,浮點包括指數符號)。

如果您需要匹配由字母和數字組成的單詞,那麼正則表達式爲[a-zA-Z\d]+。根據模塊文檔,您還需要指定要跳過的內容,並匹配[^a-zA-Z\d]+

$self->{tokenrex} = qr/([a-z\d]+)/i; 
$self->{skiprex} = qr/([^a-z\d]+)/i; 

如果需要的模塊文件顯示其例如識別數字,那麼請讓我知道了,我會很高興地補充說,早在你。從你的描述來看,這聽起來不像你所需要的。

0

所以它看起來像你有幾件事你要解決。如果我理解你的意思,那麼把這個詞分成不同的標記就很容易,只需使用非捕獲組。如果您不想在foo周圍創建新的捕獲組,請使用(?:foo);如果你這樣使用(foo)

不管怎麼說,你想要的圖案聽起來像是對我來說是這樣的:

p{L}*(?:\d*\.)?\d+(?:[eE][-+]?\d+)?(?:(?<=p{L}(?:\d*\.)?\d+(?:[eE][-+]?\d+)?)p{L}+)? 

說明:

p{L}*     #Zero or more letter characters (note that this is broader than [a-zA-Z], as it allows accent marks and so forth) 
(?:\d*\.)?\d+   #Slightly simplified version of your number-matching pattern 
(?:(?<=p{L}...)p{L}+)? #Optionally match trailing letters, but only if there are letters at the beginning 

希望我明白你在找什麼。一個問題是[eE];這將引入一些含糊之處。例如,如果你得到一個像A3E4D這樣的字符串,E是指字母還是指數?我對此有一些想法,但會更長,更復雜。讓我知道規則是什麼,我會編輯,我只是​​不想讓這更混亂,直到我確定你在找什麼。

+0

在我們的例子中,至少假設你的例子中的E是一個字母,而不是指數。順便說一下,上面的正則表達式會導致perl抱怨「可變長度lookbehind沒有實現」 – 2011-03-10 18:04:32

+0

@ gms8994 - 啊,這很不幸。它仍然是可行的,它會更長。試試這個:'p {L} +(?:\ d * \。)?\ d +(?:[eE] [ - +]?\ d +)?p {L} + |(?<!p {L} )(?:\ d * \。)?\ d +(?:[eE] [ - +]?\ d +)?(?! p {L})'應該做同樣的事情。 – 2011-03-10 19:27:36

0

(?<=...)(?=...)結構是向後看和前瞻的表達,和他們匹配的文本是包含在整個正則表達式匹配的文本

作爲一個簡單的例子,對於$_ = "A1X",正則表達式

qr/(?<=A)1(?=X)/ 

不匹配字符串$_,而是由表達式匹配的文本(比如,在$&)只是1,不A1X

你可以增加一個條款,你原來的表達式:

 
qr/([a-zA-Z]+|[a-zA-Z][a-zA-Z0-9]+[a-zA-Z]|(\d+(\.\d+)?|\d*\.\d+)([eE][-+]?\d+)?)/ 

(這將匹配A1B2C3D雖然 - 它並不清楚,如果你想讓它做)

+0

當然,它不會總是隻有3個字符;這就是爲什麼我試圖使它更通用。 – 2011-03-10 18:02:29

0

試試這個:

qr/(\b[a-zA-Z]([a-zA-Z\d]+[a-zA-Z])?\b|(\d+(\.\d+)?|\d*\.\d+)([eE][-+]?\d+)?)/ 

但是請注意,這正則表達式(與原)將在詞的「邊緣」相匹配的數字。

+0

p.s.這只是暴民解決方案的一個改進。它將前兩個選項合併爲一個。 – ridgerunner 2011-03-10 18:25:04

相關問題