提问人:maryisbiking 提问时间:11/10/2023 最后编辑:r2evansmaryisbiking 更新时间:11/10/2023 访问量:77
用于捕获两个周期之间的个位数的正则表达式
Regular expression to capture single digit between two periods
问:
我有一个名为 DataFrame 的列,其中包含从 1.1.1 到 14.8.112 的字符串。第一个数字从 1 依次增加到 14,第二个数字从 1 增加到 8,第三个数字从 1 增加到 112。我正在尝试编写一个正则表达式来捕获中间数字,它始终是 1 到 8 的个位数,而不是它周围的两个句点。day_survey_prompt
我尝试过许多正则表达式,包括后视和前瞻,除了中间数字之外,它们总是捕获一个或两个句点。例如,当 day_survey_prompt 的值为 14.5.85 时
str_extract(day_survey_prompt, "[^.]*$")
yields 和85
str_extract(day_survey_prompt, "[^.]*[.$]")
收益 率14.
在此示例中,我想要的输出是5
能让我到达那里的正则表达式是什么?
答:
前期:在您的表达式中,表示“不是字面上的点”,当后面跟着一个(“零或更多”)时,它可以匹配点以外的任何内容。同样,是与文字点或文字美元符号匹配的字符组;如果您打算说“一个点或字符串的末尾,那么在这方面会更好。同样,表示“字符串的开头或文字点”。[^.]
*
[.$]
([.]|$)
(^|[.])
使用 lookbehind () 和 lookahead () 提取 Perl 正则表达式:(?<=...)
(?=...)
ch <- c("14.8.112", "14.5.85")
regmatches(ch, gregexpr("(?<=[.])[0-9]+(?=[.])", ch, perl = TRUE))
# [[1]]
# [1] "8"
# [[2]]
# [1] "5"
gsub
-replacement,假设你总是在某个地方的两个句点之间有一个数字,并且不在乎句点之外是什么:
gsub("^[^.]*\\.([0-9]+)\\..*", "\\1", ch)
# [1] "8" "5"
在 上拆分字符串 ,.
strsplit(ch, "[.]")
# [[1]]
# [1] "14" "8" "112"
# [[2]]
# [1] "14" "5" "85"
并提取每个字符串的第二个:
strsplit(ch, "[.]") |>
sapply(`[[`, 2)
# [1] "8" "5"
如果它总是一个三元组,你可能想要第一个和第三个,我们可以将它们提取到一个框架中
strcapture("([0-9]+)\\.([0-9]+)\\.([0-9]+)", ch,
proto=list(first=0L, second=0L, third=0L))
# first second third
# 1 14 8 112
# 2 14 5 85
使用软件包(感谢您的帮助:-):stringr
# @AndyBaxter
stringr::str_extract(ch, "(?<=\\.)\\d(?=\\.)")
# @nightstand
stringr::str_extract(ch, "\\d{1,2}\\.(\\d)\\.\\d{1,3}", group=1)
(请注意,此示例将收集个位数,不高于 ,因此,如果您想要 -digit 数字,请使用 或 。此外,并且正在根据您的样本数据做出假设,如果前面/后面数字的大小未知,您可能更喜欢。9
n
\\d+
\\d{1,}
{1,2}
{1,3}
+
笔记:
- 由于是一个表示“任何字符”的正则表达式,我们需要转义它。我已经演示了两种方法,使用(反斜杠转义)或(-组中的句点,仅将 解释为文字句点),它们可以互换使用。
.
\\.
[.]
[
.
- 同样,“数字”可以正则表达式为 或 ,也可以互换
[0-9]
\\d
裁判:
- https://stackoverflow.com/a/22944075/3358272 是一般正则表达式的良好参考,请注意,它对单反斜杠的使用通常需要加倍才能在 R 中使用;
- https://www.regular-expressions.info/lookaround.html 一般的“环视”功能(不特定于 R);
- https://stackoverflow.com/a/27721009/3358272 有一些特定于 R 的细微差别,尽管大多数只是对上述内容的另一种引用
- 当然,R 中还有
正则表达式
评论
str_extract(numbers, "(?<=\\.)\\d(?=\\.)")
group
str_extract(ch, "\\d{1,2}\\.(\\d)\\.\\d{1,3}", group=1)
"...我尝试过许多正则表达式,包括后视和前瞻,除了中间数字之外,它们总是捕获一个或两个句点。..."
请尝试以下匹配模式。
(?<=\d\.)[1-8](?=\.\d)
(?<=\d\.)
,正回溯,数字和句点[1-8]
,匹配一位数,1 到 8(?=\.\d)
,积极的展望,一个时期和一个数字
或者,更准确的方法是使用捕获模式。
\b(?:1[0-4]|[1-9])\.([1-8])\.(?:11[0-2]|10\d|[1-9]\d|[1-9])\b
\b
,从单词边界开始(?:1[0-4]|[1-9])
,匹配值 1 到 14\.([1-8])\.
,在两个周期内捕获值(?:11[0-2]|10\d|[1-9]\d|[1-9])
,匹配值 1 到 112\b
,以单词边界结束
评论