2013-04-04 52 views
1

我有一個CSV::Table對象,其中包含許多列。每列由一定數量的元素組成,這些元素是應該包含數字的字符串。正則表達式檢查數字小數點分隔符是否一致

可以同時使用"."","作爲小數點分隔符,它不能有任何千位分隔符

有效例子

  • 「1023.12」
  • 「2341,34」
  • 「1245」
  • 「1.456」 - 請注意,這似乎是千個分隔符,沒有十進制的情況下,但在這種情況下,它應該被解釋爲小數分隔符
  • 「1,435」- 山姆È觀測上述

無效實例

  • 「1,434.12」
  • 「1.455,19」
  • 「1.499e5」 - 科學記數法
  • 「A134」 - 只是爲了確保字符串中沒有字符

此外,我需要確保沿所有列和行的小數分隔符是一致的;所以我需要提取使用的小數分隔符(","".")。

我可以使用什麼正則表達式來檢查字符串的有效性並提取小數點分隔符以檢查整個表的一致性?

+0

而不是檢查一致性,爲什麼不轉換爲您可以依賴的規範形式? – tadman 2013-04-04 14:34:05

+1

你會考慮'。1234'有效? – Blazemonger 2013-04-04 14:34:29

+0

@tadman實際上這是下一步;)是否有可能實現並繞過問題主題? – 2013-04-04 14:36:28

回答

3

我想這會工作:

/^\d*([.,]?)\d+$/ 

這也將讓喜歡.1234數字,這是即使他們是不同尋常的有效。

要禁止這樣的數字,嘗試將另外一對括號:

/^\d+(([.,])\d+)?$/ 

(注意,現在的第二對括號,不是第一,包含您的小數點分隔符。)

+0

我認爲科學記數法在*無效*列表中。 – 2013-04-04 14:38:34

+0

這將失敗杉木輸入「1」 – 2013-04-04 14:39:14

+0

@JoeFrambach真。我們可以將第一個+更改爲*,但是可以讓.1234通過。但是,OP說他不希望收到這個消息。 – Blazemonger 2013-04-04 14:40:52

0
matches = table.flat_map { |r| r.map { |c| /\A\d+(?:([.,])\d+)?\z/.match(c) } } 
raise 'InvalidNumbers' if matches.any?(&:nil?) 
decimals = matches.map{|m| m[1]}.reject(&:empty?).uniq 
raise 'InconsistentDecimals' if decimals.size > 1 
decimal_seperator = decimals.first || '.' 

正則表達式匹配有效數字,捕獲match [1]中的可選小數點分隔符。如果任何匹配失敗(不是數字),則會出錯。錯誤是否存在多種分隔符(不一致)。如果沒有分隔符,則假定'。'。作爲默認值。

相關問題