看板 R_Language 關於我們 聯絡資訊
※ 引述《PILIPALAPON (pilipalapon)》之銘言: : [問題類型]: : 程式諮詢 : [軟體熟悉度]: : 入門 : [問題敘述]: : 資料檔如下 : Addr : 宜蘭縣數學鎮數學里10鄰數學路100巷16之2號 : 基隆市太陽區太陽里17鄰太陽三街223之2號十九樓 : 基隆市白雲區白雲里20鄰白雲三街59號十樓之1 : 新竹市海洋區海洋里13鄰海洋路29號六樓 : 臺北市小明區小名里20鄰小名路222號二十樓 : 新北市語文區語文里17鄰語文路221號二十九樓之5 : 宜蘭縣飛機鎮飛機里3鄰飛機路73號 : 新北市紅色區紅色里15鄰紅色路四段15號之4十七樓 : 若「樓」前面有國字數字,需先轉成數字,再將每一個住址裡的數字全部抓出來。 : 這個問題除了中文數字外,還需要處理全型的數字(已問過原PO,後面確實是全型數字) 我這裡的順序是先處理全型的數字,才處理中文數字 當然也可以反過來,兩個不影響 好讀版:http://pastebin.com/srDz11gP 全型轉成半型的想法是這樣: 先行知識:字串可以轉成raw bytes的型式,多個16進位的數字表示 你可以試試看 charToRaw("123") 會出現 [1] 31 32 33 charToRaw("123") 會出現 [1] a2 b0 a2 b1 a2 b2 所以全形數字會佔去兩個16進位,可以稍微測試一下: charToRaw("0123456789") [1] a2 af a2 b0 a2 b1 a2 b2 a2 b3 a2 b4 a2 b5 a2 b6 a2 b7 a2 b8 可以看到全型的0123456789 開頭都是 a2 而結尾是af到b8 把af到b8轉成數字就是 175~184 因此,先把a2找出來,再將確定後一位是否為175~184 (全形數字) 之後再把第二個數字做位移(減去127),然後把第一個數字去掉 這樣轉換就完成了 PS: 減去127的原因是 as.integer(charToRaw("0"))是 48 as.integer(charToRaw("0")[2])是 175 兩個相差的值是127... 至於中文數字轉阿拉伯數字則是參考這篇的python code: http://www.cnblogs.com/kaituorensheng/p/3586942.html address <- c("宜蘭縣數學鎮數學里10鄰數學路100巷16之2號", "基隆市太陽區太陽里17鄰太陽三街223之2號十九樓", "基隆市白雲區白雲里20鄰白雲三街59號十樓之1", "新竹市海洋區海洋里13鄰海洋路29號六樓", "臺北市小明區小名里20鄰小名路222號二十樓", "新北市語文區語文里17鄰語文路221號二十九樓之5", "宜蘭縣飛機鎮飛機里3鄰飛機路73號", "新北市紅色區紅色里15鄰紅色路四段15號之4十七樓") library(magrittr) library(plyr) library(stringr) library(stringi) address_converted <- sapply(address, function(x){ raw_address <- charToRaw(x) loc_maybe_fullwidth_digits <- which(raw_address == "a2") second_loc <- raw_address[loc_maybe_fullwidth_digits+1] %>% as.integer loc_fullwidth_digits <- loc_maybe_fullwidth_digits[second_loc >= 175 & second_loc <= 184] + 1 raw_address[loc_fullwidth_digits] <- raw_address[loc_fullwidth_digits] %>% as.integer %>% '-'(127) %>% as.raw return(rawToChar(raw_address[setdiff(1:length(raw_address), loc_fullwidth_digits-1)])) }) %>% `names<-`(NULL) # [1] "宜蘭縣數學鎮數學里10鄰數學路100巷16之2號" # [2] "基隆市太陽區太陽里17鄰太陽三街223之2號十九樓" # [3] "基隆市白雲區白雲里20鄰白雲三街59號十樓之1" # [4] "新竹市海洋區海洋里13鄰海洋路29號六樓" # [5] "臺北市小明區小名里20鄰小名路222號二十樓" # [6] "新北市語文區語文里17鄰語文路221號二十九樓之5" # [7] "宜蘭縣飛機鎮飛機里3鄰飛機路73號" # [8] "新北市紅色區紅色里15鄰紅色路四段15號之4十七樓" chinese2digits <- function(x){ vals <- sapply(str_split(x, "")[[1]], function(chi_digit){ mapvalues(chi_digit, c("零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "百", "千", "萬", "億"), c(0:10, 10^c(2,3,4,8)), FALSE) }) %>% as.integer digit_output <- 0 base_term <- 1 for (i in rev(seq_along(vals))) { if (vals[i] >= 10 && i == 1) { base_term <- ifelse(vals[i] > base_term, vals[i], base_term * vals[i]) digit_output <- digit_output + vals[i] } else if (vals[i] >= 10) { base_term <- ifelse(vals[i] > base_term, vals[i], base_term * vals[i]) } else { digit_output <- digit_output + base_term * vals[i] } } return(digit_output) } ## test # chinese2digits("一百五十二") # 152 # chinese2digits("一億零八萬零三百二十三") # 100080323 # chinese2digits("十九") # 19 address_converted2 <- sapply(address_converted, function(x){ pattern_starts <- "[零一二三四五六七八九十百千萬億]+樓" if (!str_detect(x, pattern_starts)) return(x) stairs <- str_extract(x, pattern_starts) x <- str_replace(x, str_c("(\\d+)(", pattern_starts, ")"), "\\1, \\2") x <- str_replace(stairs, "樓", "") %>% chinese2digits %>% str_c("樓") %>% {str_replace(x, stairs, .)} return(x) }) %>% `names<-`(NULL) # [1] "宜蘭縣數學鎮數學里10鄰數學路100巷16之2號" # [2] "基隆市太陽區太陽里17鄰太陽三街223之2號19樓" # [3] "基隆市白雲區白雲里20鄰白雲三街59號10樓之1, " # [4] "新竹市海洋區海洋里13鄰海洋路29號6樓" # [5] "臺北市小明區小名里20鄰小名路222號20樓" # [6] "新北市語文區語文里17鄰語文路221號29樓之5, " # [7] "宜蘭縣飛機鎮飛機里3鄰飛機路73號" # [8] "新北市紅色區紅色里15鄰紅色路四段15號之4, 17樓" sapply(address_converted2, str_extract_all, pattern = "\\d+") # $`宜蘭縣數學鎮數學里10鄰數學路100巷16之2號` # [1] "10" "100" "16" "2" # # $基隆市太陽區太陽里17鄰太陽三街223之2號19樓 # [1] "17" "223" "2" "19" # # $`基隆市白雲區白雲里20鄰白雲三街59號10樓之1, ` # [1] "20" "59" "10" "1" # # $新竹市海洋區海洋里13鄰海洋路29號6樓 # [1] "13" "29" "6" # # $臺北市小明區小名里20鄰小名路222號20樓 # [1] "20" "222" "20" # # $`新北市語文區語文里17鄰語文路221號29樓之5, ` # [1] "17" "221" "29" "5" # # $宜蘭縣飛機鎮飛機里3鄰飛機路73號 # [1] "3" "73" # # $`新北市紅色區紅色里15鄰紅色路四段15號之4, 17樓` # [1] "15" "15" "4" "17" -- R資料整理套件系列文: magrittr #1LhSWhpH (R_Language) http://tinyurl.com/j3ql84c data.table #1LhW7Tvj (R_Language) http://tinyurl.com/hr77hrn dplyr(上) #1LhpJCfB (R_Language) http://tinyurl.com/jtg4hau dplyr(下) #1Lhw8b-s (R_Language) tidyr #1Liqls1R (R_Language) http://tinyurl.com/jq3o2g3 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 211.76.63.212 ※ 文章網址: https://www.ptt.cc/bbs/R_Language/M.1466006460.A.4DC.html
PILIPALAPON: 感謝~~ 06/16 01:45
※ 編輯: celestialgod (140.109.74.87), 06/16/2016 09:55:31
fish0331: 推一個,但數字中文轉換還是有限制,比如沒有「億」以上 08/20 13:30
fish0331: 的對應轉換,以及數字太大在電腦中計算產生溢位的疑慮。 08/20 13:30
fish0331: 不知道後來有沒有更新的手法。另外函式chinese2digits 08/20 13:30
fish0331: 中for裡的第一個if,有一點小錯誤,應該是digit_output 08/20 13:30
fish0331: <-digit_output + base_term。可以用十二萬零一百做測 08/20 13:30
fish0331: 試:) 08/20 13:30