代码之家  ›  专栏  ›  技术社区  ›  Digvijay Sawant

拆分并重新连接字符串

  •  6
  • Digvijay Sawant  · 技术社区  · 6 年前

    我正在尝试从字符串列表中获取IP地址的主机。

    ips <- c('140.112.204.42', '132.212.14.139', '31.2.47.93', '7.112.221.238')
    

    我想从IP中获取前2位数字。输出:

    ips <- c('140.112', '132.212', '31.2', '7.112')
    

    这是我为转换它们而编写的代码:

    cat(unlist(strsplit(ips, "\\.", fixed = FALSE))[1:2], sep = ".")
    

    当我最终检查单个IP的类型时,我得到如下信息:

    140.112 NULL
    

    不知道我做错了什么。如果你有其他完全不同的想法,那也很好。

    5 回复  |  直到 6 年前
        1
  •  4
  •   acylam    6 年前

    sub :

    ips <- c('140.112.204.42', '132.212.14.139', '31.2.47.93', '7.112.221.238')
    
    sub('\\.\\d+\\.\\d+$', '', ips)
    # [1] "140.112" "132.212" "31.2"    "7.112"
    

    str_extract stringr :

    library(stringr)
    str_extract(ips, '^\\d+\\.\\d+')
    # [1] "140.112" "132.212" "31.2"    "7.112"
    

    strsplit + sapply :

    sapply(strsplit(ips, '\\.'), function(x) paste(x[1:2], collapse = '.'))
    # [1] "140.112" "132.212" "31.2"    "7.112"
    

    read.table + apply :

    apply(read.table(textConnection(ips), sep='.')[1:2], 1, paste, collapse = '.')
    #[1] "140.112" "132.212" "31.2"    "7.112"
    

    笔记:

    1. sub('\\.\\d+\\.\\d+$', '', ips) :

      一。 \\.\\d+\\.\\d+$ 匹配一个文本点、一个数字一次或多次、一个文本点再次和一个数字一次或多次 在字符串的末尾

      二。 附属的 删除 上面的字符串匹配

    2. str_extract(ips, '^\\d+\\.\\d+') :

      一。 ^\\d+\\.\\d+ 一次或多次匹配一个数字,一个文本点和一个数字一次或多次匹配 在字符串的开头

      二。 str_提取物 提取物 上面的字符串匹配

    3. sapply(strsplit(ips, '\\.'), function(x) paste(x[1:2], collapse = '.')) :

      一。 strsplit(ips, '\\.') 拆分每个 ip 使用文本点作为分隔符。这将返回分割后的向量列表

      二。用 斯普林特 , paste(x[1:2], collapse = '.') 应用于列表中的每个元素,因此只从每个向量中提取前两个数字,并用一个点作为分隔符折叠它们。 斯普林特 然后将列表强制为向量,从而返回所需IP的向量。

    4. apply(read.table(textConnection(ips), sep='.')[1:2], 1, paste, collapse = '.') :

      一。 read.table(textConnection(ips), sep='.')[1:2] 对待 ips 作为文本输入并以点作为分隔符读取它。只取前两列。

      二。 应用 使能够 paste 每行操作一次,用圆点折叠。

        2
  •  4
  •   RavinderSingh13    6 年前

    你能试试看吗?

    gsub("([0-9]+.[0-9]+)(.*)","\\1",ips)
    

    说明: 使用 gsub 函数,并将regex放在那里以匹配数字,然后点,再将数字放在内存的第一个占位符中并保持 .* 之后的一切都在记忆的第二位。然后把这些换成 \\1 第一个regex的值将是前2个字段。

        3
  •  2
  •   Noah    6 年前

    一种解决方案是:

    vapply(strsplit(ips, ".", fixed = TRUE), 
           function(x) paste(x[1:2], collapse = "."), 
           character(1L))
    
    • vapply 应用 function(x) 到输出的每个元素 strsplit
    • StrSplit公司 生成一个列表,其中列表中的每个元素都是由 "." ;设置 fixed = TRUE 使用拆分字符串的确切值(即, “。” )不使用regex
    • 函数(x) 取前两个元素( x[1:2] )每件物品的 StrSplit公司 paste 他们在一起,分开 “。”
    • character(1L) 讲述 VApple 输出的每个元素(即从 函数(x) 应该是长度为1的字符串。

    编辑:@user在我面前发布了这个解决方案(使用 sapply )

        4
  •  1
  •   James    6 年前

    substr 对停止参数进行矢量化,因此可以将其与第二个点之前的位置矢量一起使用。 regexpr 给出第一场比赛的位置,所以如果你 sub 第一个你可以在第二个上匹配-这将是一个方便的,在它真正的位置之前,根据需要(因为你删除了第一个)。

    substr(ips,1,regexpr("\\.",sub("\\.","",ips)))
    [1] "140.112" "132.212" "31.2"    "7.112"
    
        5
  •  1
  •   G. Grothendieck    6 年前

    我们可以将IP地址转换为numeric_version类,然后使用不使用正则表达式的基r one行程序进行格式化:

    format(numeric_version(ips)[, 1:2])
    [1] "140.112" "132.212" "31.2"    "7.112"