2016-01-13 49 views
0
text="stack overflow... is a popular website."

正則表達式GSUBř分化省略號和週期

我想從字分離標點符號之間。輸出應爲:

"stack overflow ... is a popular website . "

當然,該命令返回gsub("\\.", " \\. ", text, fixed = FALSE)

"stack overflow . . . is a popular website . ",因爲它不時段和省略號(懸掛點)之間進行區分。簡而言之,如果在文本中找到三個句點,則R應將它們視爲單個標點符號。

+1

''GSUB不...(或'GSUB( 「([[:punct:]] +)」,「\\ 1」,text,fixed = FALSE)'對於任何類型的標點符號) – Cath

+0

只有句點,其他標點符號呢? –

+0

@stribizhev所有標點符號應與單詞分開,但省略號應被視爲單個實體,並且在過程中不得分開 – Antoine

回答

3

我認爲非環視的方式將更有效率和可讀性:

text="stack overflow... is a popular website." 
gsub("*[[:space:]]*(\\.+)[[:space:]]*", " \\1 ", text) 
## => [1] "stack overflow ... is a popular website . " 

IDEONE demo

我更新了帖子,因爲是需要空間之前和標點之後。

圍繞(\\.+)匹配零個或多個空格,並且(\\.+)將匹配一個或多個句點。 (...)形成一個捕獲組,它的值存儲在編號緩衝區#1中,我們可以使用來自替換模式的反向引用訪問它。因此,\1將被模式捕獲的時段替換。由於在當前位置之前/之後沒有檢查文本的開銷,所以捕獲比使用周邊查找效率更高。現在

如果你需要處理所有的標點,使用[[:punct:]]

gsub("[[:space:]]*([[:punct:]]+)[[:space:]]*", " \\1 ", text) 

R regex help

[:punct:]
標點符號
! " # $ % & ' () * + , - ./: ; < = > ? @ [ \ ]^_ ` { | } ~.

Code demo

text="Hi!stack overflow... is a popular website, I visit it every day." 
gsub("[[:space:]]*([[:punct:]]+)[[:space:]]*", " \\1 ", text) 
## => [1] "Hi ! stack overflow ... is a popular website , I visit it every day . " 

更新連字符的單詞

爲了避免匹配連字符的話,你可以匹配和跳過了與單詞邊界包圍了-

text="Hi!stack-overflow... is a popular website, I visit it every day." 
gsub("\\b-\\b(*SKIP)(*F)|\\s*(\\p{P}+)\\s*", " \\1 ", text, perl=T) 
## => [1] "Hi ! stack-overflow ... is a popular website , I visit it every day . " 

請參閱demo

+2

你可能至少有「upvoted」我的評論... ;-) – Cath

+0

@CathG:我寫了同樣的評論之前,但刪除它,你的是不正確的,因爲空間不是它應該在替換模式中的位置。 –

+0

正如你在我的解決方案上發表了一些評論,這不會在結束後顯示空格'。'(我的意思是查看OP的預期輸出) – akrun

2

嘗試

gsub("(?<=\\.)$|(?<=\\w)(?=\\.)", " ", text, perl=TRUE) 
#[1] "stack overflow ... is a popular website . " 

gsub("(?<=\\.)$|(?<=\\w)(?=\\.)", " ", "aaa...", perl=TRUE) 
#[1] "aaa ... " 

gsub("(?<=\\.)(?=$|\\w)|(?<=\\w)(?=\\.)", " ", "aaa...bbb", perl=TRUE) 
#[1] "aaa ... bbb" 
+1

非常感謝。如果你能簡單地解釋一下正則表達式的含義,那就太好了。 – Antoine

+1

這可能不是這個任務中最有效的正則表達式。 –

+0

好的,讓我們來看看吧,我想盡管我的帖子會有很多編輯。 –

3

這個負荷的意見後,這個正則表達式應該是最有可能滿足您的需求:

(?:\b|)([.,:;!]+)(?: |\b) 

Demo

要使用R中的反斜槓必須加倍。

所以我們最終得到:( 「(\\ +)」, 「\\ 1」,文本,固定= FALSE)

text<-c('Hi!stack-overflow... is a popular website, I visit it every day.', 
    'aaa...', 
    'AAA...B"B"B', 
    'AA .BBB #unlikely to happen but managed anyway') 

> gsub('(?:\\b|)([.,:;!]+)(?: |\\b)',' \\1 ',text) 
[1] "Hi ! stack-overflow ... is a popular website , I visit it every day . " 
[2] "aaa ... "                
[3] "AAA ... B\"B\"B"              
[4] "AA . BBB #unlikely to happen but managed anyway"  
+0

爲什麼用'(?:\ b |)?'?你在這裏有什麼意圖? –

+0

爲了確保我們處於單詞邊界或空格之間,例如可以使用一種無​​關的測試來避免由表情符號中的空格標點符號引起的環繞。 – Tensibai

+1

但[它並沒有阻止](https://regex101.com/r/tM0lR6/2)。這些組是可選的。如果你強制他們,這將工作[像這樣](https://regex101.com/r/tM0lR6/3)。 –