一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

正則表達(dá)式及R字符串處理之終結(jié)版

 gearss 2018-04-25

前一篇關(guān)于正則表達(dá)式和字符處理函數(shù)總結(jié)的博客的基礎(chǔ)上,歷時(shí)一周,我翻閱了更多的資料,進(jìn)行修改和增加了一些實(shí)例演示和案例講解,組成這一篇RClub的講座課件。本著知識(shí)共享、完全開(kāi)源的精神,在此奉獻(xiàn)給大家。


0.動(dòng)機(jī):為什么學(xué)習(xí)字符串處理

傳統(tǒng)的統(tǒng)計(jì)學(xué)教育幾乎沒(méi)有告訴過(guò)我們,如何進(jìn)行文本的統(tǒng)計(jì)建模分析。然而,我們?nèi)粘I钪薪佑|到的大部分?jǐn)?shù)據(jù)都是以文本的形式存在。文本分析與挖掘在業(yè)界中也有著非常廣泛的應(yīng)用。

由于文本數(shù)據(jù)大多屬于非結(jié)構(gòu)化的數(shù)據(jù),要想對(duì)文本數(shù)據(jù)進(jìn)行傳統(tǒng)的統(tǒng)計(jì)模型分析,必須要經(jīng)過(guò)層層的數(shù)據(jù)清洗與整理。

今天我們要介紹的『正則表達(dá)式及R字符串處理』就是用來(lái)干這一種臟活累活的。

與建立酷炫的模型比起來(lái),數(shù)據(jù)的清洗與整理似乎是一種低檔次的工作。如果把建立模型類(lèi)比于高級(jí)廚師的工作,那么,數(shù)據(jù)清洗無(wú)疑是類(lèi)似切菜洗碗打掃衛(wèi)生的活兒。然而想要成為資深的『數(shù)據(jù)玩家』,這種看似低檔次的工作是必不可少的,并且,這種工作極有可能將占據(jù)你整個(gè)建模流程的80%的時(shí)間。

如果我們能夠掌握高效的數(shù)據(jù)清洗工具,那么我們將擁有更多的時(shí)間來(lái)進(jìn)行模型選擇和參數(shù)調(diào)整,使得我們的模型更加合理有效。

此外,對(duì)于不需要進(jìn)行文本建模分析的同學(xué),掌握文本處理的工具也將對(duì)減輕你的工作負(fù)擔(dān)大有益處。下面,我舉幾個(gè)我自身經(jīng)歷的『文本處理工具讓生活更美好』的例子:

可見(jiàn),我們可以用到文本處理工具的場(chǎng)景還是非常多的,如批量文件名修改、批量字符替換、大量郵件或html文件處理等。

下面,我將通過(guò)一個(gè)例子,展示R字符串處理的大致功能。接著,介紹正則表達(dá)式的基礎(chǔ)概念。然后,介紹R字符串處理中一個(gè)非常好用的拓展包stringr,并接著介紹一些文件編碼處理相關(guān)的函數(shù)。最后,通過(guò)一兩個(gè)案例展示字符串處理的真實(shí)應(yīng)用場(chǎng)景。


1.A toy example ——初步認(rèn)識(shí)R中的字符串處理

為了先給大家一個(gè)關(guān)于R字符串處理的大體認(rèn)識(shí),我們使用R中自帶的一個(gè)數(shù)據(jù)集USArrests進(jìn)行函數(shù)功能演示。

先看看數(shù)據(jù)集的結(jié)構(gòu)。

# take a glimpse 
head(USArrests)

字符串子集提?。韩@得州的簡(jiǎn)稱(chēng)

# 獲得州名 
states = rownames(USArrests)

# 方法一:substr()
substr(x = states, start = 1, stop = 4)

# 方法二:abbreviate()

abbreviate(states,minlength = 5)

字符統(tǒng)計(jì):獲得名字最長(zhǎng)的州名

# get number of characters in each state name

state_chars <- nchar(states)

# hist
hist(nchar(states),main = "Histogram",
     xlab = "number of charaters in US State names")


# longest state's name
states[which(state_chars == max(state_chars))]

注意:nchar()與length()的區(qū)別

字符串匹配:含某些字母的州名

# get states names with 'w'
grep(pattern = "w", x = states, value = TRUE)

###########################

# get states names with 'W' OR 'w'

## Method 1:
grep(pattern = "[wW]", x = states, value = TRUE)

## Method 2:
grep(pattern = "w", x = tolower(states),value = TRUE)

## Method 3:
grep(pattern = "W", x = toupper(states), value = TRUE)

## Method 4:
grep(pattern = "w",x = states, ignore.case = TRUE, value = TRUE)

字符統(tǒng)計(jì):某些字母?jìng)€(gè)數(shù)統(tǒng)計(jì)

library(stringr)

# total number of a's
str_count(states,"a")

##################
# number of vowels

# vector of vowels
vowels <- c("a","e","i","o","u")

# vector for storing results 
num_vowels <- vector(mode = "integer",length = 5)

# calculate
for(i in seq_along(vowels)){
  num_aux <- str_count(tolower(states),vowels[i])
  num_vowels[i]<-sum(num_aux)
}

# add names
names(num_vowels)<-vowels

# total number of vowels
num_vowels

# barplot
barplot(num_vowels, main = "number of vowels in USA States names")

2.正則表達(dá)式

正則表達(dá)式是對(duì)字符串類(lèi)型數(shù)據(jù)進(jìn)行匹配判斷,提取等操作的一套邏輯公式。

處理字符串類(lèi)型數(shù)據(jù)方面,高效的工具有Perl和Python。如果我們只是偶爾接觸文本處理任務(wù),則學(xué)習(xí)Perl無(wú)疑成本太高;如果常用Python,則可以利用成熟的正則表達(dá)式模塊:re庫(kù);如果常用R,則使用Hadley大神開(kāi)發(fā)的stringr包則已經(jīng)能夠游刃有余。

下面,我們先簡(jiǎn)要介紹重要并通用的正則表達(dá)式規(guī)則。接著,總結(jié)一下stringr包中需要輸入正則表達(dá)式參數(shù)的字符處理函數(shù)。

元字符(Metacharacters)

大部分的字母和所有的數(shù)字都是匹配他們自身的正則表達(dá)式。然而,在正則表達(dá)式的語(yǔ)法規(guī)定中,有12個(gè)字符被保留用作特殊用途。他們分別是:

[ ] \ ^ $ . | ? * + ( )

如果我們直接進(jìn)行對(duì)這些特殊字符進(jìn)行匹配,是不能匹配成功的。正確理解他們的作用與用法,至關(guān)重要。

library(stringr)

metaChar = c("$","*","+",".","?","[","^","{","|","(","\\")

grep(pattern="$", x=metaChar, value=TRUE)

grep(pattern="\\", x=metaChar, value=TRUE)

grep(pattern="(", x=metaChar, value=TRUE)

gsub(pattern="|", replacement=".", "gsub|uses|regular|expressions")

strsplit(x="strsplit.aslo.uses.regular.expressions", split=".")

它們的作用如下:

  • [ ]:括號(hào)內(nèi)的任意字符將被匹配;
# example
grep(pattern = "[wW]", x = states, value = TRUE)
  • \:具有兩個(gè)作用:
    • 1.對(duì)元字符進(jìn)行轉(zhuǎn)義(后續(xù)會(huì)有介紹)
    • 2.一些以\開(kāi)頭的特殊序列表達(dá)了一些字符串組
strsplit(x="strsplit.aslo.uses.regular.expressions", split=".")

# compare
strsplit(x="strsplit.aslo.uses.regular.expressions", split="\\.")

################
# function 2:
library(stringr)
str_extract_all(string = "my cridit card number: 34901358932236",pattern = "\\d")
  • ^:匹配字符串的開(kāi)始.將^置于character class的首位表達(dá)的意思是取反義。如[^5]表示匹配除了”5”以外的任何字符。
# function 1
test_vector<-c("123","456","321")
library(stringr)
str_extract_all(test_vector,"3")
str_extract_all(test_vector,"^3")

# function 2
str_extract_all(test_vector,"[^3]")
  • $:匹配字符串的結(jié)束。但將它置于character class內(nèi)則消除了它的特殊含義。如[akm$]將匹配’a’,’k’,’m’或者’$’.
# function 1
test_vector<-c("123","456$","321")
library(stringr)
str_extract_all(test_vector,"3$")


# function 2
str_extract_all(test_vector,"[3$]")
  • .:匹配除換行符以外的任意字符。
str_extract_all(string = c("regular.expressions\n","\n"), pattern ="\\.")
  • |:或者
test_vector2<-c("AlphaGo實(shí)在厲害!","alphago是啥","阿爾法狗是一條很兇猛的狗。")
str_extract_all(string = test_vector2, pattern ="AlphaGo|阿爾法狗")
  • ?:前面的字符(組)是可有可無(wú)的,并且最多被匹配一次
str_extract_all(string = c("abc","ac","bc"),pattern = "ab?c")
  • *:前面的字符(組)將被匹配零次或多次
str_extract_all(string = c("abababab","abc","ac"),pattern = "(ab)*")
  • +:前面的字符(組)將被匹配一次或多次
str_extract_all(string = c("abababab","abc","ac"),pattern = "(ab)+")
  • ( ):表示一個(gè)字符組,括號(hào)內(nèi)的字符串將作為一個(gè)整體被匹配。
str_extract_all(string = c("ababc","ac","cde"),pattern = "(ab)?c")

str_extract_all(string = c("abc","ac","cde"),pattern = "ab?c")

重復(fù)

代碼 含義說(shuō)明
? 重復(fù)零次或一次
* 重復(fù)零次或多次
+ 重復(fù)一次或多次
{n} 重復(fù)n次
{n,} 重復(fù)n次或更多次
{n,m} 重復(fù)n次到m次
str_extract_all(string = c("abababab","ababc","ababababc"),pattern = "(ab){2,3}")

轉(zhuǎn)義

如果我們想查找元字符本身,如”?”和”*“,我們需要提前告訴編譯系統(tǒng),取消這些字符的特殊含義。這個(gè)時(shí)候,就需要用到轉(zhuǎn)義字符\,即使用\?\*.當(dāng)然,如果我們要找的是\,則使用\\進(jìn)行匹配。

strsplit(x="strsplit.aslo.uses.regular.expressions", split=".")

# compare
strsplit(x="strsplit.aslo.uses.regular.expressions", split="\\.")

注:R中的轉(zhuǎn)義字符則是雙斜杠:\\

R中預(yù)定義的字符組

代碼 含義說(shuō)明
[:digit:] 數(shù)字:0-9
[:lower:] 小寫(xiě)字母:a-z
[:upper:] 大寫(xiě)字母:A-Z
[:alpha:] 字母:a-z及A-Z
[:alnum:] 所有字母及數(shù)字
[:punct:] 標(biāo)點(diǎn)符號(hào),如. , ;
[:graph:] Graphical characters,即[:alnum:]和[:punct:]
[:blank:] 空字符,即:Space和Tab
[:space:] Space,Tab,newline,及其他space characters
[:print:] 可打印的字符,即:[:alnum:],[:punct:]和[:space:]
library(stringr)
str_extract_all(string = "my cridit card number: 34901358932236",pattern = "\\d")

代表字符組的特殊符號(hào)

代碼 含義說(shuō)明
\w 字符串,等價(jià)于[:alnum:]
\W 非字符串,等價(jià)于[^[:alnum:]]
\s 空格字符,等價(jià)于[:blank:]
\S 非空格字符,等價(jià)于[^[:blank:]]
\d 數(shù)字,等價(jià)于[:digit:]
\D 非數(shù)字,等價(jià)于[^[:digit:]]
\b Word edge(單詞開(kāi)頭或結(jié)束的位置)
\B No Word edge(非單詞開(kāi)頭或結(jié)束的位置)
\< Word beginning(單詞開(kāi)頭的位置)
\> Word end(單詞結(jié)束的位置)

3.stringr字符串處理函數(shù)對(duì)比學(xué)習(xí)

stringr包中的重要函數(shù)

函數(shù) 功能說(shuō)明 R Base中對(duì)應(yīng)函數(shù)
使用正則表達(dá)式的函數(shù)    
str_extract() 提取首個(gè)匹配模式的字符 regmatches()
str_extract_all() 提取所有匹配模式的字符 regmatches()
str_locate() 返回首個(gè)匹配模式的字符的位置 regexpr()
str_locate_all() 返回所有匹配模式的字符的位置 gregexpr()
str_replace() 替換首個(gè)匹配模式 sub()
str_replace_all() 替換所有匹配模式 gsub()
str_split() 按照模式分割字符串 strsplit()
str_split_fixed() 按照模式將字符串分割成指定個(gè)數(shù) -
str_detect() 檢測(cè)字符是否存在某些指定模式 grepl()
str_count() 返回指定模式出現(xiàn)的次數(shù) -
其他重要函數(shù)    
str_sub() 提取指定位置的字符 regmatches()
str_dup() 丟棄指定位置的字符 -
str_length() 返回字符的長(zhǎng)度 nchar()
str_pad() 填補(bǔ)字符 -
str_trim() 丟棄填充,如去掉字符前后的空格 -
str_c() 連接字符 paste(),paste0()

可見(jiàn),stringr包中的字符處理函數(shù)更豐富和完整,并且更容易記憶。

文本文件的讀寫(xiě)

這里的文本文件指的是非表格式的文件,如純文本文件,html文件。文本文件的讀取可以使用readLines()scan()函數(shù)。一般需要通過(guò)encoding = 參數(shù)設(shè)置文件內(nèi)容的編碼方式。

#假設(shè)當(dāng)前路徑有一個(gè)文件為`file.txt`
text <- readLines("file.txt", encoding = "UTF-8") 

#默認(rèn)設(shè)置,每個(gè)單詞作為字符向量的一個(gè)元素
scan("file.txt", what = character(0),encoding = "UTF-8")  

#設(shè)置成每一行文本作為向量的一個(gè)元素,這類(lèi)似于readLines
scan("file.txt", what = character(0), sep = "\n",encoding = "UTF-8")  

#設(shè)置成每一句文本作為向量的一個(gè)元素
scan("file.txt", what = character(0), sep = ".",encoding = "UTF-8")  

文本文件的寫(xiě)出可以使用cat()writeLines()函數(shù)。

# 假設(shè)要保存當(dāng)前環(huán)境中的R變量text
# sep參數(shù)指定要保存向量里的元素的分割符號(hào)。
cat(text, file = "file.txt", sep = "\n")

writeLines(text, con = "file.txt", sep = "\n", useBytes = F)

字符統(tǒng)計(jì)及字符翻譯

x<- c("I love R","I'm fascinated by Statisitcs")

##################
## 字符統(tǒng)計(jì)

# nchar
nchar(x)

# str_count
library(stringr)
str_count(x,pattern = "")
str_length(x)
######################

DNA <- "AgCTaaGGGcctTagct"

## 字符翻譯:大小寫(xiě)轉(zhuǎn)換
tolower(DNA)

toupper(DNA)
## 字符翻譯:符號(hào)替換(逐個(gè)替換)
# chartr
chartr("Tt", "Uu", DNA)  #將T堿基替換成U堿基

# 注意:與str_replace()的區(qū)別

library(stringr)
str_replace_all(string = DNA,pattern = "T",replacement = "U") %>%
  str_replace_all(string = .,pattern = "t",replacement = "u")

字符串連接

# paste
paste("control",1:3,sep = "_")

# str_c()
library(stringr)
str_c("control",1:3,sep = "_")

字符串拆分

# strsplit
text <- "I love R.\nI'm fascinated by Statisitcs."
cat(text)
strsplit(text,split = " ")
strsplit(text,split = "\\s")

# str_split
library(stringr)
str_split(text,pattern = "\\s")

字符串查詢(xún)

字符串的查詢(xún)或者搜索應(yīng)用了正則表達(dá)式的匹配來(lái)完成任務(wù). R Base 包含的字符串查詢(xún)相關(guān)的函數(shù)有g(shù)rep(),grepl(),regexpr(),gregexpr()和regexec()等。

#################################
## 包含匹配

# grep
x<- c("I love R","I'm fascinated by Statisitcs","I")
grep(pattern = "love",x = x)
grep(pattern = "love",x = x,value = TRUE)
grepl(pattern = "love",x = x)

# str_detect

str_detect(string = x, pattern = "love")

#################################
# 
# match,完全匹配, 常用的 %in% 由match()定義
match(x = "I",table = x)
"I'm" %in% x

字符串替換

sub()和gsub()能夠提供匹配替換的功能,但其替換的實(shí)質(zhì)是先創(chuàng)建一個(gè)對(duì)象,然后對(duì)原始對(duì)象進(jìn)行重新賦值,最后結(jié)果好像是“替換”了一樣。

sub()和gsub()的區(qū)別在于,前者只替換第一次匹配的字串(請(qǐng)注意輸出結(jié)果中world的首字母),而后者會(huì)替換掉所有匹配的字串。

也可以使用substr和substring對(duì)指定位置進(jìn)行替換。

#####################################
## 匹配替換

test_vector3<-c("Without the vowels,We can still read the word.")


# sub
sub(pattern = "[aeiou]",replacement = "-",x = test_vector3)

# gsub
gsub(pattern = "[aeiou]",replacement = "-",x = test_vector3)

# str_replace_all
  
str_replace_all(string = test_vector3,pattern = "[aeiou]",
                replacement = "-")


##########################################
## 指定位置替換

字符串提取

常用到的提取函數(shù)有substr()和substring(),它們都是靠位置來(lái)進(jìn)行提取的,它們自身并不適用正則表達(dá)式,但是它們可以結(jié)合正則表達(dá)式函數(shù)regexpr(),gregexpr()和regexec()等可以方便地從文本中提取所需信息。

stringr包中的函數(shù)str_substr_dup可以通過(guò)位置提取,而str_extractstr_match可以通過(guò)正則表達(dá)式提取。

substr("abcdef", start = 2, stop = 4)
substring("abcdef", first = 1:6, last = 2:7)

str_sub("abcdef",start = 2, end = 4)
str_sub("abcdef",start = 1:6, end = 1:6)

################################


text_weibo<- c("#圍棋人機(jī)大戰(zhàn)# 【人工智能攻克圍棋 AlphaGo三比零完勝李世石】","谷歌人工智能AlphaGo與韓國(guó)棋手李世石今日進(jìn)行了第三場(chǎng)較量","最終AlphaGo戰(zhàn)勝李世石,連續(xù)取得三場(chǎng)勝利。接下來(lái)兩場(chǎng)將淪為李世石的“榮譽(yù)之戰(zhàn)。")

# str_match_all,返回的列表中的元素為矩陣

str_match_all(text_weibo,pattern = "#.+#")

str_match_all(text_weibo, pattern = "[a-zA-Z]+")

# str_extract_all,返回的列表中的元素為向量
str_extract_all(text_weibo,pattern = "#.+#")

str_extract_all(text_weibo, pattern = "[a-zA-Z]+")

字符串定制輸出

這個(gè)內(nèi)容有點(diǎn)類(lèi)似于字符串的連接。R中相應(yīng)的函數(shù)為strtrim(),用于將字符串修剪到特定的顯示寬度。stringr中相應(yīng)的函數(shù)為:str_pad().

strtrim()會(huì)根據(jù)width參數(shù)提供的數(shù)字來(lái)修剪字符串,若width提供的數(shù)字大于字符串的字符數(shù)的話,則該字符串會(huì)保持原樣,不會(huì)增加空格之類(lèi)的東西,若小于,則刪除部分字符。而str_pad()則相反。

strtrim(c("abcde", "abcde", "abcde"),width =  c(1, 5, 10))

str_pad(string = c("abcde", "abcde", "abcde"),width =  c(1, 5, 10),side = "right")

strwrap()會(huì)把字符串當(dāng)成一個(gè)段落來(lái)處理(不管段落中是否有換行),按照段落的格式進(jìn)行縮進(jìn)和分行,返回結(jié)果就是一行行的字符串。

而str_wrap()不對(duì)文本直接切割成向量,而是在文本內(nèi)容中插入了縮進(jìn)或分行的標(biāo)識(shí)符。

string <- "Each character string in the input is first split into\n paragraphs (or lines containing whitespace only). The paragraphs are then formatted by breaking lines at word boundaries."

strwrap(x = string, width = 30)

#str_wrap
str_wrap(string = string,width = 30)
cat(str_wrap(string = string, width = 30))

4.字符編碼相關(guān)的重要函數(shù)

windows下處理字符串類(lèi)型數(shù)據(jù)最頭疼的無(wú)疑是編碼問(wèn)題了。這里介紹幾個(gè)編碼轉(zhuǎn)換相關(guān)的函數(shù)。

函數(shù) 功能說(shuō)明
iconv() 轉(zhuǎn)換編碼格式
Encoding() 查看編碼格式;或者指定編碼格式
tau::is.locale() tests if the components of a vector of character are in the encoding of the current locale
tau::is.ascii()  
tau::is.utf8() tests if the components of a vector of character are true UTF-8 strings

雖然查看編碼方式已經(jīng)有Encoding()函數(shù),但是這個(gè)函數(shù)往往在很多時(shí)候都不靈,經(jīng)常返回惱人的“Unknow”。而火狐瀏覽器進(jìn)行網(wǎng)頁(yè)文本編碼識(shí)別的一個(gè) c++ 庫(kù)universalchardet ,可以識(shí)別的編碼種類(lèi)較多。文鋒寫(xiě)了一個(gè)相應(yīng)的R包接口,專(zhuān)用于文件編碼方式檢測(cè),具體請(qǐng)參考:checkenc - 自動(dòng)文本編碼識(shí)別

devtools::install_github("qinwf/checkenc")
library(checkenc)
checkenc("2016-03-10-regular-expression-and-strings-processing-in-R.html")

Encoding("2016-03-10-regular-expression-and-strings-processing-in-R.html")

5.應(yīng)用案例

最后,給大家展示一個(gè)小小的爬蟲(chóng)案例:爬取豆瓣T250中的電影信息進(jìn)行分析。這里出于練習(xí)的目的刻意使用了字符串處理函數(shù),在實(shí)際的爬蟲(chóng)中,有更方便快捷的實(shí)現(xiàn)方式。

本案例改編自肖凱老師的博客在R語(yǔ)言中使用正則表達(dá)式,原博客使用R Base中的函數(shù)進(jìn)行處理字符串,這里已經(jīng)全部更改為stringr中的函數(shù)進(jìn)行處理。

library(stringr)
library(dplyr)

url <-'http://movie.douban.com/top250?format=text'
# 獲取網(wǎng)頁(yè)原代碼,以行的形式存放在web變量中
setInternet2()
web <- readLines(url,encoding="UTF-8")
# 找到包含電影名稱(chēng)的行
name<-str_extract_all(string = web, pattern = '<span class="title">.+</span>')
movie.names_line <- unlist(name)
# 用正則表達(dá)式來(lái)提取電影名
movie.names <- str_extract(string = movie.names_line, pattern = ">[^&].+<") %>% str_replace_all(string = ., pattern = ">|<",replacement = "") 

movie.names<- na.omit(movie.names)

# 獲取評(píng)價(jià)人數(shù)
Rating<- str_extract_all(string = web,pattern = '<span>[:digit:]+人評(píng)價(jià)</span>')

Rating.num_line<-unlist(Rating)

Rating.num<- str_extract(string = Rating.num_line, pattern = "[:digit:]+") %>% as.numeric(.)

#獲取評(píng)價(jià)分?jǐn)?shù)
Score_line<-str_extract_all(string = web, pattern = '<span class="rating_num" property="v:average">[\\d\\.]+</span>')

Score_line<- unlist(Score_line)

Score<- str_extract(string = Score_line, pattern = '\\d\\.\\d') %>%
  as.numeric(.)

# 數(shù)據(jù)合并

MovieData<- data.frame(MovieName = movie.names,
                       RatingNum = Rating.num,
                       Score = Score,
                       Rank = seq(1,25),stringsAsFactors = FALSE)
View(MovieData)
#可視化
library(ggplot2)
ggplot(data = MovieData,aes(x = Rank,y = Score)) +
  geom_point(aes(size = RatingNum))+
 geom_text(aes(label = MovieName), colour = "blue",size = 4,vjust = -0.6)

深入學(xué)習(xí)

參考文獻(xiàn)


? 2016 yphuang ? Powered by Jekyll.                 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多

    视频一区二区 国产精品| 国产精品一区二区日韩新区| 欧美日韩乱一区二区三区| 91人妻人人精品人人爽| 国产传媒免费观看视频| 国产精品一区二区传媒蜜臀| 精品欧美日韩一区二区三区| 亚洲国产精品国自产拍社区| 蜜桃av人妻精品一区二区三区| 不卡中文字幕在线免费看| 亚洲一区二区三区三州| 日韩女优精品一区二区三区| 欧美精品中文字幕亚洲| 色哟哟在线免费一区二区三区 | 亚洲国产精品久久网午夜| 欧美日韩在线视频一区| 国产高清一区二区白浆| 丰满人妻熟妇乱又伦精另类视频 | 高清在线精品一区二区| 久久黄片免费播放大全 | 丝袜视频日本成人午夜视频| 视频一区日韩经典中文字幕| 91偷拍与自偷拍精品| 国产毛片对白精品看片| 日韩精品一区二区毛片| 日韩精品一区二区一牛| 日系韩系还是欧美久久| 在线免费视频你懂的观看| 国产一区二区精品丝袜| 白丝美女被插入视频在线观看| 亚洲免费视频中文字幕在线观看| 两性色午夜天堂免费视频| 蜜桃臀欧美日韩国产精品| 亚洲国产成人精品福利| 亚洲精品国产美女久久久99| 亚洲国产精品久久网午夜| 91精品视频免费播放| 欧美一区二区三区播放| 午夜精品在线视频一区| 超碰在线播放国产精品| 亚洲天堂国产精品久久精品|