簡體   English   中英

抓n字母的字不算撇號正則表達式

[英]grab n letter words don't count apostrophes regex

我正在努力更深入地學習R中的正則表達式。 我給了自己一些我認為不容易理解的簡單任務。 我想提取所有4個字母的單詞。 在這四個字母的單詞中我想忽略(不要算)撇號。 我可以在沒有正則表達式的情況下執行此操作但需要正則表達式解決方案 這是一個MWE和我嘗試過的:

text.var <- "This Jon's dogs' 'bout there in Mike's re'y word."
pattern <- "\\b[A-Za-z]{4}\\b(?!')"
pattern <- "\\b[A-Za-z]{4}\\b|\\b[A-Za-z']{5}\\b"

regmatches(text.var, gregexpr(pattern, text.var, perl = TRUE)) 

**期望的輸出:**

[[1]]
[1] "This"  "Jon's"  "dogs'"  "'bout"  "word"

我認為第二種模式可行,但它也會抓取包含5個字符的單詞。

這是一個很有挑戰性的問題,這是一個棘手的答案。

> x  <- "This Jon's dogs' 'bout there in Mike's re'y word."
> re <- "(?i)('?[a-z]){5,}(*SKIP)(?!)|('?[a-z]){4}'?"
> regmatches(x, gregexpr(re, x, perl=T))[[1]]
## [1] "This"  "Jon's" "dogs'" "'bout" "word" 

說明

想法是跳過由5個或更多字母字符和可選撇號組成的任何單詞模式。

在交替運算符的左側,我們匹配我們不想要的子模式。 使其失敗並強制正則表達式引擎不使用回溯控制重試子字符串。 如下所述:

(*SKIP) # advances to the position in the string where (*SKIP) was 
        # encountered signifying that what was matched leading up 
        # to cannot be part of the match

(?!)    # equivalent to (*FAIL), causes matching failure, 
        # forcing backtracking to occur

交替操作員的右側符合我們想要的......

附加說明:

  • 從本質上講,簡單來說就是使用丟棄技術

     (?:'?[az]){5,}|((?:'?[az]){4}'?) 

    你可以在上下文中使用交替運算符,將你要排除的內容放在左邊( 說丟掉它,它是垃圾 )並在右側的捕獲組中放置你想要匹配的內容。

您可以使用此模式:

(?i)(?<![a-z'])(?:'?[a-z]){4}'?(?![a-z'])

你可以使用discard技術並使用這樣的正則表達式:

\b\w{0,2}\b(?:'\w)?|\b\w{3}(?!')\b|\b\w{5,}\b|('?\b\w+\b'?\w?)

工作演示

在此輸入圖像描述

MATCH 1
1.  [0-4]   `This`
MATCH 2
1.  [5-10]  `Jon's`
MATCH 3
1.  [11-16] `dogs'`
MATCH 4
1.  [17-22] `'bout`
MATCH 5
1.  [32-36] `word`

對於R,需要轉義特殊字符。

正如您在正則表達式模式中所看到的那樣,您可以在模式的左側使用您不想要的任何內容,並將您真正想要的內容留在最右側的捕獲組中。 丟棄技術背后的想法是:

discard this|don't want this|still don't care this|(Oh yeah! I grab this)

感謝 EdConttrelljohnwait幫助我改進答案。

編輯兩次:(感謝hex494D49 ):

(?i)(?<=\\W|^)(?<!')'*(?:\\w{4}|\\w'*\\w{3}|\\w{2}'*\\w{2}|\\w{3}'*\\w|\\w{2}'*\\w'*\\w|\\w'*\\w{2}'*\\w|\\w'*\\w'*\\w{2}|\\w'*\\w'*\\w'*\\w)'*(?!')(?=\\W|$)

更好地適應所有可能的情況......

但是 ,問題的標題是:

grab n letter words don't count apostrophes regex

所以我推薦我的解決方案。

我認為另一個解決方案可能會更清晰/更簡潔:

正則表達式

(?<![\w'])(?:'?\w'?){4}(?![\w'])

說明

(?<![\w'])

這是一個否定的Lookbehind斷言:它檢查匹配前面沒有' char或一個字char( \\w[a-zA-Z] )。

(?:'?\w'?){4}

這匹配任何單詞char,可選地在'之后/之后。 (?: ... )使組無法捕獲。

(?![\w'])

這是一個否定前瞻斷言,確保該組不會跟隨另一個撇號或字母char。


第一個和最后一個術語的目的是確保中間組的4個匹配不被更多字符包圍:即該單詞只有4個字母。

它們或多或少等同於\\b字邊界檢測,除了它們將撇號計為單詞的一部分,而\\b則不是。

問題

正則表達式不匹配以雙撇號開頭或結尾的字符串'' 我不認為這是一個巨大的損失。

請在regex101.com上查看此鏈接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM