簡體   English   中英

所有大寫的駝峰式字符串

[英]Camel case string from all caps

我有一個包含數千個表和列的數據庫。 列名始終采用所有大寫字母,例如 BOOKINGPROCESSNOTEADDED、BOOKEDDATETIME、BOOKINGSTATUS。 我希望重命名列,以便它們是小寫的駝峰式,例如 BOOKINGSTATUS -> booking_status

因為單詞、空格或下划線之間的大小寫沒有變化,所以基本上不可能應用更傳統的方法將字符串轉換為不同的大小寫(例如使用 R 的snakecase包)。 我想知道是否可以在每個字符串上應用某種英語詞典查找並返回拆分。

以上面的 BOOKINGSTATUS 為例,返回值可能是:boo_king_status、boo_king_stat_us 和 booking_status。 指定單詞的最小長度會很有用。 如果最小值設置為 4 個字母,則在此示例中僅返回 booking_status(因為“boo”只有 3 個字母,“us”只有 2 個字母)

蠻力方法很可能在計算上過於昂貴,但想問一下是否有合理有效的方法來做到這一點。 Python 或 R 解決方案將是最受歡迎的。

library(dplyr)
library(stringr)

add_spaces <- function(colnames, words) {
  for(i in 1:length(colnames)) {
    for(j in words) {
      if(str_detect(string = colnames[i], pattern = j)) {
        colnames[i] <- str_replace(string = colnames[i], j, glue::glue("{str_to_lower(j)}_"))
      }
    }
  }
 
  colnames <- colnames %>% 
    str_remove("\\_+$") # Remove hyphens at the end
  
  message("Characters not identified: ")
  print(str_remove_all(colnames, "[a-z_]"))
  
  invisible(colnames)
}
   
colnames <- names(<file>) # Capture colnames  # Using c("BOOKINGPROCESSNOTEADDED", "BOOKEDDATETIME", "BOOKINGSTATUS")

words <- c("BOOKING", "BOOKED", "PROCESS") # Create first list of words

colnames <- add_spaces(colnames, words) # Run the first iteration        

> Characters not identified:
[1] "NOTEADDED" "DATETIME"  "STATUS"

words <- c(words, "NOTE", "ADDED", "DATE", "TIME", "STATUS") # Augment list with missing words

colnames <- add_spaces(colnames, words) # Rerun, ... repeat as needed
    
colnames 

[1] "booking_process_note_added" "booked_date_time"           "booking_status" 

這是一個草率的、蠻力的、不完美的嘗試。 它幾乎肯定會錯過一些東西。 其實更多的是關於過程的對話,希望你能建立一個更好的“詞典”。

首先,關於這個“字典”的討論:理想情況下,它應該包含一個單詞及其復數*ing*ed forms。 我們將嘗試用蛇形包裝( _word_ )版本替換每個單詞,因此我們將根據長度以相反的順序排列 go。 出於理智,我們可能應該刪除太短的單詞( and , an , a ),所以讓我們從stringr::words開始(只是“用於練習字符串操作的示例字符向量” ,不是一個好的開始)。

words <- stringr::words[ order(nchar(stringr::words), decreasing = TRUE) ]
# see words[nchar(words) < 4] for what we are removing here
words <- words[nchar(words) > 3]
Reduce(function(txt, ptn) gsub(ptn, paste0("_", ptn ,"_"), txt, perl = TRUE),
       toupper(words), init = vec)
# [1] "_BOOK_ING_PROCESS__NOTE_ADDED" "_BOOK_ED_DATE__TIME_"          "_BOOK_INGSTATUS"              

這看起來很奇怪,當然。 我們可以注意到,我們知道向量中的一些單詞在stringr::words中丟失了:

c("booking", "process", "status") %in% words
# [1] FALSE  TRUE FALSE

我們可以擴充我們的列表:

words2 <- c(words, "booking", "booked", "status")
words2 <- words2[ order(nchar(words2), decreasing = TRUE) ]
Reduce(function(txt, ptn) gsub(ptn, paste0("_", ptn ,"_"), txt, perl = TRUE),
       toupper(words2), init = vec)
# [1] "__BOOK_ING__PROCESS__NOTE_ADDED" "__BOOK_ED__DATE__TIME_"          "__BOOK_ING__STATUS_"            

這里的問題是,由於我們同時擁有"booking""book" ,它總是會雙重更改"BOOKING" 鑒於我從這里開始的天真,我不知道除了刪除"book" (順便說一句,還有"king" )之外還有一個簡單的快速補丁。

words3 <- setdiff(words2, c("book", "king"))
Reduce(function(txt, ptn) gsub(ptn, paste0("_", ptn ,"_"), txt, perl = TRUE),
       toupper(words3), init = vec)
# [1] "_BOOKING__PROCESS__NOTE_ADDED" "_BOOKED__DATE__TIME_"          "_BOOKING__STATUS_"            

從這里,我們可以刪除前導/尾隨和雙_

gsub("__", "_",
     gsub("^_|_$", "", 
          Reduce(function(txt, ptn) gsub(ptn, paste0("_", ptn ,"_"), txt, perl = TRUE),
                 toupper(words3), init = vec)))
# [1] "BOOKING_PROCESS_NOTE_ADDED" "BOOKED_DATE_TIME"           "BOOKING_STATUS"            

質量完全取決於從一本好的詞典開始。 如果您的所有 UPPERNOSPACEWORDS 都已明確定義,那么也許您可以手動構建它。 (請注意,有些單詞可能只是自我隔離,因為前后都有一個已知單詞(請注意, "added"不在words3中,但它仍然被分解)。

我會手動構建字典:

  • 從空字典開始
  • 獲取所有名稱
  • 找到一個包含大寫的
  • 手動將單詞添加到字典中以拆分該單詞
  • 使用當前字典將它們全部拆分

重復最后 3 個步驟,直到所有單詞都被拆分。 例如,對於您發布的 3 個名稱,字典將首先獲取c("booking", "status") ,並且該名稱沒有大寫字母。 名稱BOOKINGPROCESSNOTEADDED將變為booking_PROCESSNOTEADDED 如果你選擇了這個,你會添加c("process", "note", "added")到字典中,然后找到BOOKEDDATETIME 現在您需要確定單詞:是c("booked", "date", "time")還是c("booked", "datetime")

等等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM