18-R文本处理函数stringr

字符串在平常的数据处理中经常用到,需要对其进行分割、连接、转换等操作,灵活的字符串处理,可以有效地提高代码的编写效率。
stringr包一共提供了30个函数,方便我们对字符串处理。常用的字符串处理以str_开头来命名,方便更直观理解函数的定义。

1、字符串拼接函数
str_c:字符串拼接,同paste和paste0
str_join: 字符串拼接,同str_c
str_trim: 去掉字符串的空格和TAB(\t)
str_pad: 补充字符串的长度
str_dup: 复制字符串
str_wrap: 控制字符串输出格式
str_sub: 截取字符串
str_sub <- :截取字符串,并赋值,同str_sub

2、字符串计算函数
str_count:字符串计数
str_length:字符串长度
str_sort: 字符串值排序
str_order:字符串索引排序,规则同str_sort

3、字符串匹配函数
str_split: 字符串分割
str_split_fixed:字符串分割,同str_split
str_subset:返回匹配的整个字符串
word:从文本中提取单词
str_detect:检查匹配字符串的字符,返回TRUE或FALSE
str_match:从字符串中提取匹配组,返回结果为list
str_match_all:从字符串中提取匹配组,同str_match,但返回结果为matrix
str_replace:字符串替换,只替换第一个出现的匹配
str_replace_all:字符串替换,同str_replace,替换所有匹配
str_replace_na:把NA替换为其他任意字符串
str_locate:找到第一个匹配的字符串的位置
str_locate_all:找到所有匹配的字符串的位置,以matrix返回
str_extract:从字符串中提取匹配字符,返回list
str_extract_all:从字符串中提取匹配字符,同str_extract,返回matrix

4、字符串变换函数
str_conv:字符编码转换
str_to_upper:字符串转成大写
str_to_lower:字符串转成小写,规则同str_to_upper
str_to_title:字符串转成首字母大写,规则同str_to_upper

参数控制函数,仅用于构造功能的参数,不能独立使用
boundary:定义使用边界
coll:定义字符串标准排序规则。
fixed:定义用于匹配的字符,包括正则表达式中的转义符
regex:定义正则表达式

1、字符串拼接函数

(1)str_c,字符串拼接操作

与str_join完全相同,与paste()行为不完全一致。
函数定义:

str_c(..., sep = "", collapse = NULL)
str_join(..., sep = "", collapse = NULL)

参数列表:
…: 多参数的输入
sep: 把多个字符串拼接为一个大的字符串,用于字符串的分割符
collapse: 把多个向量参数拼接为一个大的字符串,用于字符串的分割符。

library(pacman)
p_load(stringr)

#把多个字符串拼接为一个大的字符串
a <- "白日依山尽,"
b <- "黄河入海流。"
c <- "欲穷千里目,"
d <- "更上一层楼。"

str_c(a, b)
## [1] "白日依山尽,黄河入海流。"
ab <- str_c(a, b, sep='-');ab
## [1] "白日依山尽,-黄河入海流。"
str_c(c(a, b),c(c, d),sep='-')
## [1] "白日依山尽,-欲穷千里目," "黄河入海流。-更上一层楼。"
#把多个向量参数拼接为一个大的字符串
str_c(head(letters), collapse = "")
## [1] "abcdef"
str_c(head(letters), collapse = ", ")
## [1] "a, b, c, d, e, f"
# collapse参数,对多个字符串无效
str_c(a, b, collapse = "-")   
## [1] "白日依山尽,黄河入海流。"
str_c(c(a, c),c(b,d),collapse='-')
## [1] "白日依山尽,黄河入海流。-欲穷千里目,更上一层楼。"
#拼接有NA值的字符串向量时,NA还是NA
str_c(c(a, NA, b), c)
## [1] "白日依山尽,欲穷千里目," NA                         "黄河入海流。欲穷千里目,"

(2)str_c()与paste()函数对比

paste与paste0的区别:paste()的函数sep默认为空格" ",paste0()函数sep默认为无""。

# 多字符串拼接,默认的sep参数行为不一致
str_c(a, b)
## [1] "白日依山尽,黄河入海流。"
paste(a, b)
## [1] "白日依山尽, 黄河入海流。"
# 向量拼接字符串,collapse参数的行为一致
str_c(head(letters), collapse = "")
## [1] "abcdef"
paste(head(letters), collapse = "")
## [1] "abcdef"
#拼接有NA值的字符串向量,对NA的处理行为不一致
str_c(c(a, NA, b), c)
## [1] "白日依山尽,欲穷千里目," NA                         "黄河入海流。欲穷千里目,"
paste(c(a, NA, b), c)
## [1] "白日依山尽, 欲穷千里目," "NA 欲穷千里目,"           "黄河入海流。 欲穷千里目,"

(3)str_trim,去掉字符串的空格和TAB(\t)

函数定义:
str_trim(string, side = c("both", "left", "right"))
参数列表:
string: 字符串,字符串向量
side: 过滤方式,both两边都过滤,left左边过滤,right右边过滤

#只过滤左边的空格
str_trim("  left space\t\n",side='left') 
## [1] "left space\t\n"
#只过滤右边的空格
str_trim("  left space\t\n",side='right')
## [1] "  left space"
#过滤两边的空格
str_trim("  left space\t\n",side='both')
## [1] "left space"
#过滤两边的空格
str_trim("\nno space\n\t")
## [1] "no space"

(4)str_pad,补充字符串的长度

函数定义:
str_pad(string, width, side = c("left", "right", "both"), pad = " ")
参数列表:
string: 字符串,字符串向量
width: 字符串填充后的长度
side: 填充方向,both两边都填充,left左边填充,right右边填充
pad: 用于填充的字符

# 从左边补充空格,直到字符串长度为20
str_pad(a, 20, "left")
## [1] "        白日依山尽,"
# 从右边补充空格,直到字符串长度为20
str_pad(b, 20, "right")
## [1] "黄河入海流。        "
# 从左右两边各补充空格,直到字符串长度为20
str_pad(c, 20, "both")
## [1] "    欲穷千里目,    "
# 从左右两边各补充x字符,直到字符串长度为20
str_pad(d, 20, "both",'*')
## [1] "****更上一层楼。****"

(5)str_dup,复制字符串

函数定义:
str_dup(string, times)
参数列表:
string: 字符串,字符串向量。
times: 复制数量

val <- c(a, 123, b)

# 复制2次
str_dup(val, 2)
## [1] "白日依山尽,白日依山尽," "123123"                   "黄河入海流。黄河入海流。"
# 按位置复制
str_dup(val, 1:length(val))
## [1] "白日依山尽,"                         "123123"                              
## [3] "黄河入海流。黄河入海流。黄河入海流。"

(6)str_wrap,控制字符串输出格式

函数定义:
str_wrap(string, width = 80, indent = 0, exdent = 0)
参数列表:
string: 字符串,字符串向量
width: 设置一行所占的宽度
indent: 段落首行的缩进值
exdent: 段落非首行的缩进值

txt <- 'R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。
随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。'

# 设置宽度为40个字符
cat(str_wrap(txt, width = 40), "\n")
## R语言作为统计学一门语言,一直在小众领域
## 闪耀着光芒。直到大数据的爆发,R语言变成
## 了一门炙手可热的数据分析的利器。随着越来
## 越多的工程背景的人的加入,R语言的社区在
## 迅速扩大成长。现在已不仅仅是统计领域,教
## 育,银行,电商,互联网….都在使用R语言。
# 设置宽度为60字符,首行缩进2字符
cat(str_wrap(txt, width = 60, indent = 2), "\n")
##   R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数
## 据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来
## 越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已
## 不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。
# 设置宽度为10字符,非首行缩进4字符
cat(str_wrap(txt, width = 10, exdent = 4), "\n")
## R语言作为
##     统计学一
##     门语言,
##     一直在小
##     众领域闪
##     耀着光芒。
##     直到大数据
##     的爆发,R
##     语言变成了
##     一门炙手可
##     热的数据分
##     析的利器。
##     随着越来
##     越多的工程
##     背景的人的
##     加入,R语
##     言的社区在
##     迅速扩大成
##     长。现在已
##     不仅仅是统
##     计领域,教
##     育,银行,
##     电商,互联
##     网….都在使
##     用R语言。

(7)str_sub,截取字符串

函数定义:
str_sub(string, start = 1L, end = -1L)
参数列表:
string: 字符串,字符串向量。
start : 开始位置
end : 结束位置

txt <- str_c(a,b,c,d)

# 截取1-4的索引位置的字符串
str_sub(txt, 1, 4)
## [1] "白日依山"
# 截取1-6的索引位置的字符串
str_sub(txt, end=6)
## [1] "白日依山尽,"
# 截取第6到结束的索引位置的字符串
str_sub(txt, 6)
## [1] ",黄河入海流。欲穷千里目,更上一层楼。"
# 分2段截取字符串,1-6,4-8
str_sub(txt, c(1, 4), c(6, 8))
## [1] "白日依山尽," "山尽,黄河"
# 通过负坐标截取字符串
str_sub(txt, -3)
## [1] "层楼。"
str_sub(txt, end = -3)
## [1] "白日依山尽,黄河入海流。欲穷千里目,更上一层"
#对截取的字符串进行赋值
x <- "AAABBBCCC"

# 在字符串1到1的位置赋值为1
str_sub(x, 1, 1) <- 1; x
## [1] "1AABBBCCC"
# 在字符串从2到-2的位置赋值为2345
str_sub(x, 2, -2) <- "2345"; x
## [1] "12345C"

2、字符串计算函数

(1)str_count, 字符串计数

函数定义:
str_count(string, pattern = "")
参数列表:
string: 字符串,字符串向量
pattern: 匹配的字符

#对字符串中匹配的字符计数
str_count('aaa444sssddd', "a")
## [1] 3
fruit <- c("apple", "banana", "pear", "pineapple")
str_count(fruit, "a")
## [1] 1 3 1 1
str_count(fruit, "p")
## [1] 2 0 1 3
#对字符串中的'.'字符计数,由于.是正则表达式的匹配符,代表任意字符,所以直接判断计数的结果是不对的。此时相当于str_length()函数
str_count(c("a.", ".", ".a.",NA), ".")
## [1]  2  1  3 NA
# 用fixed匹配字符
str_count(c("a.", ".", ".a.",NA), fixed("."))
## [1]  1  1  2 NA
# 用\\匹配字符
str_count(c("a.", ".", ".a.",NA), "\\.")
## [1]  1  1  2 NA

(2)str_length,字符串长度

函数定义:
str_length(string)
参数列表:
string: 字符串,字符串向量

#计算字符串的长度:
str_length(c("I", "am", "王菲", NA))
## [1]  1  2  2 NA

(3)str_sort,字符串值排序,同str_order索引排序

函数定义:
str_sort(x, decreasing = FALSE, na_last = TRUE, locale = "", ...)
str_order(x, decreasing = FALSE, na_last = TRUE, locale = "", ...)
参数列表:
x: 字符串,字符串向量
decreasing: 排序方向
na_last: NA值的存放位置,一共3个值,TRUE放到最后,FALSE放到最前,NA过滤处理
locale: 按哪种语言习惯排序

# 对字符串值进行排序
# 按ASCII字母排序
str_sort(c('a',1,2,'11'), locale = "en")  
## [1] "1"  "11" "2"  "a"
# 倒序排序
str_sort(letters,decreasing=TRUE)  
##  [1] "z" "y" "x" "w" "v" "u" "t" "s" "r" "q" "p" "o" "n" "m" "l" "k" "j" "i" "h" "g" "f" "e" "d" "c"
## [25] "b" "a"
# 按拼音排序
str_sort(c('你','好','啊','我','的','朋','友'),locale = "zh")  
## [1] "啊" "的" "好" "你" "朋" "我" "友"
#对NA值的排序处理
#把NA放最后面
str_sort(c(NA,'1',NA),na_last=TRUE) 
## [1] "1" NA  NA
#把NA放最前面
str_sort(c(NA,'1',NA),na_last=FALSE) 
## [1] NA  NA  "1"
#去掉NA值 
str_sort(c(NA,'1',NA),na_last=NA)    
## [1] "1"

3、字符串匹配函数

(1)str_split,字符串分割,同str_split_fixed

函数定义:
str_split(string, pattern, n = Inf)
str_split_fixed(string, pattern, n)
参数列表:
string: 字符串,字符串向量
pattern: 匹配的字符
n: 分割个数

#对字符串进行分割
val <- "abc,123,234,iuuu"

# 以,进行分割
s1 <- str_split(val, ",");s1
## [[1]]
## [1] "abc"  "123"  "234"  "iuuu"
# 以,进行分割,保留2块
s2<-str_split(val, ",", 2);s2
## [[1]]
## [1] "abc"          "123,234,iuuu"
# 查看str_split()函数操作的结果类型list
class(s1)
## [1] "list"
# 用str_split_fixed()函数分割,结果类型是matrix
s3<-str_split_fixed(val, ",",2);s3
##      [,1]  [,2]          
## [1,] "abc" "123,234,iuuu"
class(s3)
## [1] "matrix"

(2)str_subset,返回匹配的字符串

函数定义:
str_subset(string, pattern)
参数列表:
string: 字符串,字符串向量
pattern: 匹配的字符

val <- c("abc", 123, "cba")

# 全文匹配
str_subset(val, "a")
## [1] "abc" "cba"
# 开头匹配
str_subset(val, "^a")
## [1] "abc"
# 结尾匹配
str_subset(val, "a$")
## [1] "cba"

(3)word,从文本中提取单词

函数定义:
word(string, start = 1L, end = start, sep = fixed(" "))
参数列表:
string: 字符串,字符串向量
start: 开始位置
end: 结束位置
sep: 匹配字符

val <- c("I am QQ.", "http://www.qq.com, ok")

# 默认以空格分割,取第一个位置的字符串
word(val, 1)
## [1] "I"                  "http://www.qq.com,"
# 默认以空格分割,取最后一个位置的字符串
word(val, -1)
## [1] "QQ." "ok"
word(val, 2, -1)
## [1] "am QQ." "ok"
# 以,分割,取第一个位置的字符串 
val<-'111,222,333,444'
word(val, 1, sep = fixed(','))
## [1] "111"
word(val, 3, sep = fixed(','))
## [1] "333"

(4)str_detect,匹配字符串的字符

注意与str_match的区别。
函数定义:
str_detect(string, pattern)
参数列表:
string: 字符串,字符串向量
pattern: 匹配字符

val <- c("abca4", 123, "cba2")

# 检查字符串向量,是否包括a
str_detect(val, "a")
## [1]  TRUE FALSE  TRUE
# 检查字符串向量,是否以a为开头
str_detect(val, "^a")
## [1]  TRUE FALSE FALSE
# 检查字符串向量,是否以a为结尾
str_detect(val, "a$")
## [1] FALSE FALSE FALSE

(5)str_match,从字符串中提取匹配组

注意和str_subset()函数的区别。
函数定义:
str_match(string, pattern)
str_match_all(string, pattern)
参数列表:
string: 字符串,字符串向量
pattern: 匹配字符

#从字符串中提取匹配组
val <- c("abc", 123, "cba")

# 匹配字符a,并返回对应的字符
str_match(val, "a")
##      [,1]
## [1,] "a" 
## [2,] NA  
## [3,] "a"
# 匹配字符0-9,限1个,并返回对应的字符
str_match(val, "[0-9]")
##      [,1]
## [1,] NA  
## [2,] "1" 
## [3,] NA
# 匹配字符0-9,不限数量,并返回对应的字符
str_match(val, "[0-9]*")
##      [,1] 
## [1,] ""   
## [2,] "123"
## [3,] ""
#从字符串中提取匹配组,以字符串matrix格式返回
str_match_all(val, "a")
## [[1]]
##      [,1]
## [1,] "a" 
## 
## [[2]]
##      [,1]
## 
## [[3]]
##      [,1]
## [1,] "a"
str_match_all(val, "[0-9]")
## [[1]]
##      [,1]
## 
## [[2]]
##      [,1]
## [1,] "1" 
## [2,] "2" 
## [3,] "3" 
## 
## [[3]]
##      [,1]

(6)str_replace,字符串替换

函数定义:
str_replace(string, pattern, replacement)
参数列表:
string: 字符串,字符串向量
pattern: 匹配字符
replacement: 用于替换的字符

val <- c("abc", 123, "cba")

# 把目标字符串第一个出现的a或b,替换为-
str_replace(val, "[ab]", "-")
## [1] "-bc" "123" "c-a"
# 把目标字符串所有出现的a或b,替换为-
str_replace_all(val, "[ab]", "-")
## [1] "--c" "123" "c--"
# 把目标字符串所有出现的a,替换为被转义的字符
str_replace_all(val, "[a]", "\1\1")
## [1] "\001\001bc" "123"        "cb\001\001"

(7)str_replace_na,把NA替换为任意字符串

函数定义:
str_replace_na(string, replacement = "NA")
参数列表:
string: 字符串,字符串向量。
replacement : 用于替换的字符。

#把NA替换为字符串
str_replace_na(c(NA,'NA',"abc"),'x')
## [1] "x"   "NA"  "abc"

(8)str_locate,找到模式在字符串中的位置

函数定义:
str_locate(string, pattern)
str_locate_all(string, pattern)
参数列表:
string: 字符串,字符串向量
pattern: 匹配字符

val <- c("abca", 123, "cba")

# 匹配a在字符串中的位置
str_locate(val, "a")
##      start end
## [1,]     1   1
## [2,]    NA  NA
## [3,]     3   3
# 用向量匹配
str_locate(val, c("a", 12, "b"))
##      start end
## [1,]     1   1
## [2,]     1   2
## [3,]     2   2
# 以字符串matrix格式返回
str_locate_all(val, "a")
## [[1]]
##      start end
## [1,]     1   1
## [2,]     4   4
## 
## [[2]]
##      start end
## 
## [[3]]
##      start end
## [1,]     3   3
# 匹配a或b字符,以字符串matrix格式返回
str_locate_all(val, "[ab]")
## [[1]]
##      start end
## [1,]     1   1
## [2,]     2   2
## [3,]     4   4
## 
## [[2]]
##      start end
## 
## [[3]]
##      start end
## [1,]     2   2
## [2,]     3   3

(9)str_extract,从字符串中提取匹配模式的字符

函数定义:
str_extract(string, pattern)
str_extract_all(string, pattern, simplify = FALSE)
参数列表:
string: 字符串,字符串向量
pattern: 匹配字符
simplify: 返回值,TRUE返回matrix,FALSE返回字符串向量

val <- c("abca4", 123, "cba2")

# 返回匹配的数字
str_extract(val, "\\d")
## [1] "4" "1" "2"
# 返回匹配的字符
str_extract(val, "[a-z]+")
## [1] "abca" NA     "cba"
str_extract_all(val, "\\d")
## [[1]]
## [1] "4"
## 
## [[2]]
## [1] "1" "2" "3"
## 
## [[3]]
## [1] "2"
str_extract_all(val, "[a-z]+")
## [[1]]
## [1] "abca"
## 
## [[2]]
## character(0)
## 
## [[3]]
## [1] "cba"

4、字符串变换函数

(1)str_conv,字符编码转换

函数定义:
str_conv(string, encoding)
参数列表:
string: 字符串,字符串向量
encoding: 编码名

# 对中文进行转码处理
# 把中文字符字节化
x <- charToRaw('你好');x
## [1] c4 e3 ba c3
# 默认win系统字符集为GBK,GB2312为GBK字集,转码正常
str_conv(x, "GBK")
## [1] "你好"
str_conv(x, "GB2312")
## [1] "你好"
# 转UTF-8失败
str_conv(x, "UTF-8")
## Warning in stri_conv(string, encoding, "UTF-8"): input data \xffffffc4 in the current source encoding
## could not be converted to Unicode
## Warning in stri_conv(string, encoding, "UTF-8"): input data \xffffffe3\xffffffba in the current
## source encoding could not be converted to Unicode
## Warning in stri_conv(string, encoding, "UTF-8"): input data \xffffffc3 in the current source encoding
## could not be converted to Unicode
## [1] "<U+FFFD><U+FFFD><U+FFFD>"
#把unicode转UTF-8
x1 <- "\u5317\u4eac"
str_conv(x1, "UTF-8")
## [1] "北京"

(2)str_to_upper,字符串大写转换

函数定义:
str_to_upper(string, locale = "")
参数列表:
string: 字符串
locale:按哪种语言习惯排序

#字符串大写转换
val <- "I am KG. Welcome to my blog! http://kg.me"

# 全大写
str_to_upper(val)
## [1] "I AM KG. WELCOME TO MY BLOG! HTTP://KG.ME"

(3)str_to_lower,字符串小写转换

函数定义:
str_to_lower(string, locale = "")
参数列表:
string: 字符串
locale:按哪种语言习惯排序

# 全小写
str_to_lower(val)
## [1] "i am kg. welcome to my blog! http://kg.me"

(4)str_to_title,字符串首字母大写转换

函数定义:
str_to_title(string, locale = "")
参数列表:
string: 字符串
locale:按哪种语言习惯排序

# 首字母大写
str_to_title(val)
## [1] "I Am Kg. Welcome To My Blog! Http://Kg.me"
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容