如何检测字符串中的所有字母字符(> = 2个字符)是否为大写?最后,我试图过滤掉章节标题名称,即我的数据集中的行。因此,如果一个章节标题是" ARYA",我想要检测到,与" THE QUEEN' S HAND"相同。
这是我尝试但不起作用的地方:
library(dplyr)
library(stringr)
str_detect("THE QUEEN’S HAND", "^[[:upper:]]{2,}+$")
#> FALSE
我需要的要求:
toupper(x) == (x)
解决方案,则可以检测到此类问题,例如" THE QUEEN' HAND"。我也试图摆脱带有感叹号或句号的东西,例如"停止这个!" 答案 0 :(得分:15)
所有字母字符均为大写字母。
与
相同不是单个字母字符是小写字母。
如果您真的想使用正则表达式完成此任务,那么您需要编写的是:
! str_detect("THE QUEEN’S HAND", "[[:lower:]]")
您可以对其进行测试here。
如果您想考虑字符串长度,可以添加logical OR:
nchar(str) < 2 || ! str_detect(str, "[[:lower:]]")
您可以对其进行测试here。
答案 1 :(得分:13)
您可能(?)在分析的错误阶段执行此操作
您似乎正在尝试对ASOIAF进行文本分析,并从分析中排除章节标题,但我认为您正试图在分析中的错误点进行。章节标题在原始文本中很容易识别,因为它们始终位于页面顶部,始终居中并始终跟随间隙。这些功能可以让您轻松可靠地识别标题,但在您尝试识别标题之前,这些信息已被丢弃。如果您掌握了分析的这一阶段,那么您可能更容易确定在此阶段哪些条目是标题。
您不需要正则表达式来执行此操作
虽然您在问题标题中指定了Regex,但它不包含在问题正文中,因此我假设您实际上并不需要它,但最终只是寻找Regex解决方案来解决不需要的问题。
测试所有大写字母的最简单方法是x == toupper(x)
。 toupper()
会将所有字母字符转换为大写字母形式,然后您可以通过将其与此转换后的版本进行比较来测试您的字符串是否全部为大写。
筛选长度小于2的字符串也很简单,只需添加nchar(x) >=2
条件即可完成此操作。
您的最终要求不是那么简单,但您需要确切地确定您需要排除的条件。我怀疑如果你得到完整的段落(?)那么最好的方法是寻找引号。根据需要匹配的选项范围,您可能需要在此处使用Regex,但如果只有少数特定标记,则可以使用str_detect
(来自stringr
包)与{ {1}}检测它的选项,因为它会快得多。
无论你是否在最后阶段使用Regex,我都会将检测包含在函数中的一系列条件中,而不是进行单一的Regex搜索,因为这样会更快,在我看来,概念上更容易理解。
答案 2 :(得分:10)
修改强>
我最初认为如果长度为<2,则要忽略小写字母。如果你想确保所有这些字母是大写的,但只有当整个字符串的长度是> = 2时,一个更简单的正则表达式才会这样做:< / p>
^(?:[A-Z](?:[^A-Za-z\r\n])*){2,}$
或者如果你想匹配长度为&gt; = 2 的字符串,即使它只包含一个字母(例如“A @”):
^(?=.{2})(?:[A-Z](?:[^A-Za-z\r\n])*)+$
原始回答:
这是一个仅限正则表达式的解决方案,只检查字符是否为大写,如果它们是&gt; = 2:
^(?:[A-Z]{2,}(?:[^A-Za-z\r\n]|[A-Za-z](?![a-z]))*)+$
或者:
^(?:[[:upper:]]{2,}(?:[^[:alpha:]\r\n]|[[:alpha:]](?![[:lower:]]))*)+$
<强>故障:强>
^
:在行/字符串的开头处断言位置。(?:
:开始第一个非捕获组。
[A-Z]
:匹配任何大写的英语字母。 1 {2,}
:匹配前一个字符的两次或多次。(?:
:开始第二个非捕获组。
[^A-Za-z\r\n]
:匹配任何不是英语字母或行终止符的字符。 2 |
:或。[A-Za-z]
:匹配任何英语字母。 3 (?!
:开始否定的Lookahead。
[a-z]
:匹配任何小写的英语字母。 4 )
:负面的Lookahead结束。)
:第二个非捕获组的结束。*
:匹配前一组的零次或多次。)
:第一个非捕获组的结束。+
:匹配前一组的一次或多次。$
:断言位于行/字符串注意:要将整个字符串视为一行,只需删除\r\n
部分。
[[:upper:]]
。 [^[:alpha:]\r\n]
。 [[:alpha:]]
。 [[:lower:]]
。 答案 3 :(得分:5)
我理解这一点:
有了这个,我认为这个正则表达式应该足够了:
^(.|[^[:lower:]]{2,})$
哪个是
的分离^.$
^[^[:lower:]]{2,}$
尝试一下:
> str_detect("THE QUEEN’S HAND", "^(.|[^[:lower:]]{2,})$")
[1] TRUE
> str_detect("THE QUEEN’S HaND", "^(.|[^[:lower:]]{2,})$")
[1] FALSE
> str_detect("i", "^(.|[^[:lower:]]{2,})$")
[1] TRUE
> str_detect("I", "^(.|[^[:lower:]]{2,})$")
[1] TRUE
> str_detect("ii", "^(.|[^[:lower:]]{2,})$")
[1] FALSE
答案 4 :(得分:4)
修改强>
要注意字符串所包含的字符数,我们可以nchar
使用ifelse
而不更改正则表达式。
str <- "THE QUEEN'S HAND"
ifelse(nchar(str) >= 2 , grepl("^[A-Z]+$" , gsub("[^A-Za-z]","", str)), FALSE)
#[1] TRUE
str <- "THE QUEEN's HAND"
ifelse(nchar(str) >= 2 , grepl("^[A-Z]+$" , gsub("[^A-Za-z]","", str)), FALSE)
#[1] FALSE
str <- "T"
ifelse(nchar(str) >= 2 , grepl("^[A-Z]+$" , gsub("[^A-Za-z]","", str)), FALSE)
#[1] FALSE
或者@Konrad Rudolph评论说我们可以使用逻辑运算符来避免ifelse
检查。
str <- c("THE QUEEN'S HAND", "THE QUEEN's HAND", "T")
nchar(str) >= 2 & grepl("^[A-Z]+$" , gsub("[^A-Za-z]","", str))
#[1] TRUE FALSE FALSE
原始答案
我们首先用空格(&#34;&#34;)替换所有非字母字符gsub
,然后将其与toupper
进行比较。
text = gsub("[^a-zA-Z]+", "", "THE QUEENS HAND")
text
#[1] "THEQUEENSHAND"
text == toupper(text)
#[1] TRUE
对于小写字母的字符串,它将返回FALSE
text = gsub("[^a-zA-Z]+", "", "THE QUEENs HAND")
text == toupper(text)
#[1] FALSE
正如@SymbolixAU评论的那样,我们只能使用grepl
和gsub
grepl("^[A-Z]+$" , gsub("[^A-Za-z]","", "THE QUEEN'S HAND"))
#[1] TRUE
grepl("^[A-Z]+$" , gsub("[^A-Za-z]","", "THE QUEEN's HAND"))
#[1] FALSE
答案 5 :(得分:3)
如果我理解你的问题,你想接受以下字符串:
如果这是正确的,那么你的答案就差不多了。但你的只接受大写字母而不是接受任何小写字符。
以下正则表达式应该有效:
^[^[:lower:]]{2,}+$
答案 6 :(得分:2)
要保持在stringr
上下文中,请使用str_replace_all
仅获取字母字符,然后使用str_detect
检查大写字母:
string1 <- "THE QUEEN’S HAND"
string2 <- "T"
string1 %>%
str_replace_all(., "[^a-zA-Z]", "") %>%
str_detect(., "[[:upper:]]{2,}")
# TRUE
string2 %>%
str_replace_all(., "[^a-zA-Z]", "") %>%
str_detect(., "[[:upper:]]{2,}")
# FALSE