分割并重新连接字符串

时间:2018-07-20 17:51:02

标签: r string

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

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

我想从ips获取前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 个答案:

答案 0 :(得分:4)

使用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)

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

    ii。 sub 从字符串中删除以上

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

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

    ii。 str_extract 从字符串中提取匹配

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

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

    ii。对于sapplypaste(x[1:2], collapse = '.')应用于列表的每个元素,因此仅取每个向量的前两个数字,并用点折叠作为分隔符。 sapply然后将列表强制为向量,从而返回所需ips的向量。

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

    i。 read.table(textConnection(ips), sep='.')[1:2]ips视为文本输入,并以点作为定界符读取它。仅占据前两列。

    ii。 apply使paste可以在每一行上操作,并以点折叠。

答案 1 :(得分:4)

请您尝试以下。

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

说明: :使用gsub函数并将regex放在此处以匹配数字,然后DOT然后将数字放入内存的第一位,并保留.*所有内容在第二名之后然后用\\1用第一个正则表达式的值替换这两个值,这将是前2个字段。

答案 2 :(得分:2)

以下是一种解决方案:

vapply(strsplit(ips, ".", fixed = TRUE), 
       function(x) paste(x[1:2], collapse = "."), 
       character(1L))
  • vapplyfunction(x)应用于strsplit的输出的每个元素
  • strsplit生成一个列表,其中列表的每个元素都是由"."分隔的IP地址的组成部分;设置fixed = TRUE的请求使用拆分字符串的确切值(即".")进行拆分,而不使用正则表达式
  • function(x)将每个项目的前两个元素(x[1:2])从strsplit中提取出来,并将它们paste在一起,并用"."隔开
  • character(1L)告诉vapply,输出的每个元素(即从function(x)返回的字符串都应是长度为1的字符串。

编辑:@useR在我之前(使用sapply)发布了该解决方案。

答案 3 :(得分:1)

substr在stop参数上被矢量化,因此可以将其与第二个点之前的位置矢量一起使用。 regexpr给出了第一个匹配项的位置,因此,如果您sub出了第一个匹配项,则可以在第二个匹配项上进行匹配-根据需要,这将很方便地在其真实位置之前(因为您删除了第一个匹配项) )。

substr(ips,1,regexpr("\\.",sub("\\.","",ips)))
[1] "140.112" "132.212" "31.2"    "7.112"

答案 4 :(得分:1)

我们可以将ip地址转换为numeric_version类,然后使用不使用正则表达式的基本R一线格式进行格式化:

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