正则表达式、R 和逗号
Regex, R, and Commas
我在使用 R 中的正则表达式字符串时遇到了一些问题。我正在尝试使用正则表达式从字符串(从网络上抓取)中提取标签,如下所示:
str <- "\n\n\n \n\n\n “Don't cry because it's over, smile because it happened.”\n ―\n Dr. Seuss\n\n\n\n\n \n tags:\n attributed-no-source,\n cry,\n crying,\n experience,\n happiness,\n joy,\n life,\n misattributed-dr-seuss,\n optimism,\n sadness,\n smile,\n smiling\n \n \n 176513 likes\n \n\n\n\n\nLike\n\n"
# Why doesn't this work at all?
stringr::str_match(str, "tags:(.+)\d")
[,1] [,2]
[1,] NA NA
# Why just the first tag? What happens at the comma?
stringr::str_match(str, "tags:\n(.+)")
[,1] [,2]
[1,] "tags:\n attributed-no-source," " attributed-no-source,"
所以有两个问题——为什么我的第一个想法行不通,为什么第二个想法没有捕获到字符串的末尾,而不仅仅是第一个逗号?
谢谢!
请注意 stringr
正则表达式风格是 ICU 的风格。与 TRE 不同,.
不匹配 ICU 正则表达式模式中的换行符。
因此,一个可能的解决方法是使用 (?s)
- 一个 DOTALL 修饰符,使 .
匹配任何字符,包括换行字符 - 在模式的开头:
str_match(str, "(?s)tags:(.+)\d")
和
str_match(str, "(?s)tags:\n(.+)")
但是,我觉得您好像需要将 tags:
下面的所有字符串作为单独的匹配项。我建议使用基本 R regmatches
/ gregexpr
和 PCRE 正则表达式,如
(?:\G(?!\A),?|tags:)\R\h*\K[^\s,]+
查看您的数据 regex demo。
(?:\G(?!\A),?|tags:)
- 将上一次成功匹配的结尾与后面的 1 或 0 ,
(\G(?!\A),?
) 或 (|
) tags:
匹配子串
\R
- 换行序列
\h*
- 0+ 水平空格
\K
- 匹配重置运算符,丢弃目前匹配的所有文本
[^\s,]+
- 除了空格和 ,
之外的 1 个或更多字符
参见 R demo:
str <- "\n\n\n \n\n\n “Don't cry because it's over, smile because it happened.”\n ―\n Dr. Seuss\n\n\n\n\n \n tags:\n attributed-no-source,\n cry,\n crying,\n experience,\n happiness,\n joy,\n life,\n misattributed-dr-seuss,\n optimism,\n sadness,\n smile,\n smiling\n \n \n 176513 likes\n \n\n\n\n\nLike\n\n"
reg <- "(?:\G(?!\A),?|tags:)\R\h*\K[^\s,]+"
vals <- regmatches(str, gregexpr(reg, str, perl=TRUE))
unlist(vals)
结果:
[1] "attributed-no-source" "cry" "crying"
[4] "experience" "happiness" "joy"
[7] "life" "misattributed-dr-seuss" "optimism"
[10] "sadness" "smile" "smiling"
我在使用 R 中的正则表达式字符串时遇到了一些问题。我正在尝试使用正则表达式从字符串(从网络上抓取)中提取标签,如下所示:
str <- "\n\n\n \n\n\n “Don't cry because it's over, smile because it happened.”\n ―\n Dr. Seuss\n\n\n\n\n \n tags:\n attributed-no-source,\n cry,\n crying,\n experience,\n happiness,\n joy,\n life,\n misattributed-dr-seuss,\n optimism,\n sadness,\n smile,\n smiling\n \n \n 176513 likes\n \n\n\n\n\nLike\n\n"
# Why doesn't this work at all?
stringr::str_match(str, "tags:(.+)\d")
[,1] [,2]
[1,] NA NA
# Why just the first tag? What happens at the comma?
stringr::str_match(str, "tags:\n(.+)")
[,1] [,2]
[1,] "tags:\n attributed-no-source," " attributed-no-source,"
所以有两个问题——为什么我的第一个想法行不通,为什么第二个想法没有捕获到字符串的末尾,而不仅仅是第一个逗号?
谢谢!
请注意 stringr
正则表达式风格是 ICU 的风格。与 TRE 不同,.
不匹配 ICU 正则表达式模式中的换行符。
因此,一个可能的解决方法是使用 (?s)
- 一个 DOTALL 修饰符,使 .
匹配任何字符,包括换行字符 - 在模式的开头:
str_match(str, "(?s)tags:(.+)\d")
和
str_match(str, "(?s)tags:\n(.+)")
但是,我觉得您好像需要将 tags:
下面的所有字符串作为单独的匹配项。我建议使用基本 R regmatches
/ gregexpr
和 PCRE 正则表达式,如
(?:\G(?!\A),?|tags:)\R\h*\K[^\s,]+
查看您的数据 regex demo。
(?:\G(?!\A),?|tags:)
- 将上一次成功匹配的结尾与后面的 1 或 0,
(\G(?!\A),?
) 或 (|
)tags:
匹配子串\R
- 换行序列\h*
- 0+ 水平空格\K
- 匹配重置运算符,丢弃目前匹配的所有文本[^\s,]+
- 除了空格和,
之外的 1 个或更多字符
参见 R demo:
str <- "\n\n\n \n\n\n “Don't cry because it's over, smile because it happened.”\n ―\n Dr. Seuss\n\n\n\n\n \n tags:\n attributed-no-source,\n cry,\n crying,\n experience,\n happiness,\n joy,\n life,\n misattributed-dr-seuss,\n optimism,\n sadness,\n smile,\n smiling\n \n \n 176513 likes\n \n\n\n\n\nLike\n\n"
reg <- "(?:\G(?!\A),?|tags:)\R\h*\K[^\s,]+"
vals <- regmatches(str, gregexpr(reg, str, perl=TRUE))
unlist(vals)
结果:
[1] "attributed-no-source" "cry" "crying"
[4] "experience" "happiness" "joy"
[7] "life" "misattributed-dr-seuss" "optimism"
[10] "sadness" "smile" "smiling"