【问题标题】:R - Extract city name from two-word stringsR - 从两个单词的字符串中提取城市名称
【发布时间】:2018-02-21 20:48:09
【问题描述】:

我正在使用一个包含如下城市名称的数据库:

cities <- c("Fairhope 3NE", "Gadsden 19N", "Selma 13 WNW", "Batesville 8 WNW", 
"Elgin 5 S", "Tucson 11 W", "Williams 35 NNW", "Fallbrook 5 NE", 
"Stovepipe Wells 1 SW", "Cortez 8 SE", "La Junta 17 WSW", "Montrose 11 ENE", 
"Everglades City 5 NE", "Sebring 23 SSE", "Brunswick 23 S", "Newton 11 SW", 
"Newton 8 W", "Watkinsville 5 SSE", "Des Moines 17 E", "Champaign 9 SW", 
"Shabbona 5 NNE", "Bedford 5 WNW", "Manhattan 6 SSW", "Oakley 19 SSW", 
"Bowling Green 21 NNE", "Versailles 3 NNW", "Lafayette 13 SE", 
"Monroe 26 N", "Goodridge 12 NNW", "Chillicothe 22 ENE", "Joplin 24 N", 
"Salem 10 W", "Holly Springs 4 N", "Newton 5 ENE", "Asheville 13 S", 
"Asheville 8 SSW", "Durham 11 W", "Jamestown 38 WSW", "Medora 7 E", 
"Northgate 5 ESE", "Harrison 20 SSE", "Lincoln 11 SW", "Lincoln 8 ENE", 
"Whitman 5 ENE", "Las Cruces 20 N", "Los Alamos 13 W", "Socorro 20 N", 
"Mercury 3 SSW", "Coshocton 8 NNE", "Goodwell 2 E", "Stillwater 2 W", 
"Stillwater 5 WNW", "Coos Bay 8 SW", "Corvallis 10 SSW", "Riley 10 WSW", 
"Blackville 3 W", "McClellanville 7 NE", "Aberdeen 35 WNW", "Buffalo 13 ESE", 
"Pierre 24 S", "Sioux Falls 14 NNE", "Crossville 7 NW", "Austin 33 NW", 
"Bronte 11 NNE", "Edinburg 17 NNE", "Monahans 6 ENE", "Muleshoe 19 S", 
"Palestine 6 WNW", "Panther Junction 2 N", "Necedah 5 WNW")

我只想提取城市名称。以下代码适用于某些情况:

gsub( " .*$", "", cities)

但对于具有两个单词名称的城市(例如 Stovepipe Wells 1 SWLa Junta 17 WSW)则失败。

对这些案例有什么解决方案的想法吗?

【问题讨论】:

    标签: r regex string gsub


    【解决方案1】:

    您可以删除所有以数字开头的子字符串:

    > sub("\\s*\\d.*", "", cities)
     [1] "Fairhope"         "Gadsden"          "Selma"            "Batesville"       "Elgin"            "Tucson"           "Williams"         "Fallbrook"        "Stovepipe Wells" 
    [10] "Cortez"           "La Junta"         "Montrose"         "Everglades City"  "Sebring"          "Brunswick"        "Newton"           "Newton"           "Watkinsville"    
    [19] "Des Moines"       "Champaign"        "Shabbona"         "Bedford"          "Manhattan"        "Oakley"           "Bowling Green"    "Versailles"       "Lafayette"       
    [28] "Monroe"           "Goodridge"        "Chillicothe"      "Joplin"           "Salem"            "Holly Springs"    "Newton"           "Asheville"        "Asheville"       
    [37] "Durham"           "Jamestown"        "Medora"           "Northgate"        "Harrison"         "Lincoln"          "Lincoln"          "Whitman"          "Las Cruces"      
    [46] "Los Alamos"       "Socorro"          "Mercury"          "Coshocton"        "Goodwell"         "Stillwater"       "Stillwater"       "Coos Bay"         "Corvallis"       
    [55] "Riley"            "Blackville"       "McClellanville"   "Aberdeen"         "Buffalo"          "Pierre"           "Sioux Falls"      "Crossville"       "Austin"          
    [64] "Bronte"           "Edinburg"         "Monahans"         "Muleshoe"         "Palestine"        "Panther Junction" "Necedah"         
    > 
    

    这里,

    • \\s* - 匹配 0+ 个空格
    • \\d - 一个数字
    • .* - 字符串的其余部分。

    请参阅regex demosub 只执行一次匹配和替换操作。

    【讨论】:

      【解决方案2】:

      假设每个字符串都以相同的模式结束:

      • 空间
      • 数字
      • 可选空格,
      • 组合ENSW

      See code in use here

      gsub(" \\d+ ?[ENSW]+$", "", cities)
      

      结果:

       [1] "Fairhope"         "Gadsden"          "Selma"            "Batesville"      
       [5] "Elgin"            "Tucson"           "Williams"         "Fallbrook"       
       [9] "Stovepipe Wells"  "Cortez"           "La Junta"         "Montrose"        
      [13] "Everglades City"  "Sebring"          "Brunswick"        "Newton"          
      [17] "Newton"           "Watkinsville"     "Des Moines"       "Champaign"       
      [21] "Shabbona"         "Bedford"          "Manhattan"        "Oakley"          
      [25] "Bowling Green"    "Versailles"       "Lafayette"        "Monroe"          
      [29] "Goodridge"        "Chillicothe"      "Joplin"           "Salem"           
      [33] "Holly Springs"    "Newton"           "Asheville"        "Asheville"       
      [37] "Durham"           "Jamestown"        "Medora"           "Northgate"       
      [41] "Harrison"         "Lincoln"          "Lincoln"          "Whitman"         
      [45] "Las Cruces"       "Los Alamos"       "Socorro"          "Mercury"         
      [49] "Coshocton"        "Goodwell"         "Stillwater"       "Stillwater"      
      [53] "Coos Bay"         "Corvallis"        "Riley"            "Blackville"      
      [57] "McClellanville"   "Aberdeen"         "Buffalo"          "Pierre"          
      [61] "Sioux Falls"      "Crossville"       "Austin"           "Bronte"          
      [65] "Edinburg"         "Monahans"         "Muleshoe"         "Palestine"       
      [69] "Panther Junction" "Necedah"   
      

      【讨论】:

      • 感谢您的回答。它是被接受的,因为a)它有效,b)它是第一个(根据SO报告的时间)。
      【解决方案3】:

      你可以使用

      gsub("(\\D+)\\s+.*", "\\1", cities)
      

      屈服

       [1] "Fairhope"         "Gadsden"          "Selma"            "Batesville"       "Elgin"           
       [6] "Tucson"           "Williams"         "Fallbrook"        "Stovepipe Wells"  "Cortez"          
      [11] "La Junta"         "Montrose"         "Everglades City"  "Sebring"          "Brunswick"       
      [16] "Newton"           "Newton"           "Watkinsville"     "Des Moines"       "Champaign"       
      [21] "Shabbona"         "Bedford"          "Manhattan"        "Oakley"           "Bowling Green"   
      [26] "Versailles"       "Lafayette"        "Monroe"           "Goodridge"        "Chillicothe"     
      [31] "Joplin"           "Salem"            "Holly Springs"    "Newton"           "Asheville"       
      [36] "Asheville"        "Durham"           "Jamestown"        "Medora"           "Northgate"       
      [41] "Harrison"         "Lincoln"          "Lincoln"          "Whitman"          "Las Cruces"      
      [46] "Los Alamos"       "Socorro"          "Mercury"          "Coshocton"        "Goodwell"        
      [51] "Stillwater"       "Stillwater"       "Coos Bay"         "Corvallis"        "Riley"           
      [56] "Blackville"       "McClellanville"   "Aberdeen"         "Buffalo"          "Pierre"          
      [61] "Sioux Falls"      "Crossville"       "Austin"           "Bronte"           "Edinburg"        
      [66] "Monahans"         "Muleshoe"         "Palestine"        "Panther Junction" "Necedah"        
      


      解释,这说:
      (\\D+) # not a digit, 1+ times
      \\s+   # at least one whitespace
      .*     # rest of the string
      

      然后将其替换为第一个捕获的组,在本例中为 \\1

      【讨论】:

      • 所以我想“如果一个城市的名称中有一个数字字符怎么办?”。这并不常见(根本不常见),但显然,一些俄罗斯城市曾经有数字Krasnoyask-26。许多closed cities 都这样做了。只是觉得这是一本有趣的书!
      • @ctwheels:我不知道这个。但是,OP 的城市对我来说确实看起来很美国,不是吗?也可能是加拿大人...
      • 哦,我完全同意,你的回答很好(而且很简单),我显然只是想打破它并发现它,认为它很有趣:)
      【解决方案4】:

      这应该可行:

      gsub( " [1-9].*$", "", cities)
      

      【讨论】:

        【解决方案5】:

        这个正则表达式应该可以在任何地方使用,包括 R:.+?(?=\ \d)

        它包括直到第一个空格后跟一个数字的所有内容。

        【讨论】:

          猜你喜欢
          • 2018-06-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多