文字列内のすべての英字(> = 2文字)が大文字であるかどうかを検出するにはどうすればよいですか?最終的に、章のタイトル名(データセットの行)を除外しようとしています。したがって、チャプターのタイトルが「ARYA」の場合、「THE QUEEN'S HAND」と同じように、それを検出してほしい。
これが私が試していることですが、うまくいきません:
_library(dplyr)
library(stringr)
str_detect("THE QUEEN’S HAND", "^[[:upper:]]{2,}+$")
#> FALSE
_
私が必要とする要件:
toupper(x) == (x)
ソリューションを使用すると、これは「THE QUEEN'S HAND」のようなものと一緒に検出されます。また、「STOP THIS!」のように感嘆符やピリオドが付いているものをすべて削除しようとしています。すべての英字は大文字です。
と同じです
単一の英字は小文字ではありません。
このタスクに本当に正規表現を使用したい場合は、次のように記述するだけです。
! str_detect("THE QUEEN’S HAND", "[[:lower:]]")
あなたはそれをテストすることができます ここ 。
文字列の長さを考慮したい場合は、 logical OR を追加できます。
nchar(str) < 2 || ! str_detect(str, "[[:lower:]]")
あなたはそれをテストすることができます ここ 。
おそらく(?)分析の間違った段階でこれを行っています
ASOIAFのテキスト分析を行い、章の見出しを分析から除外しようとしているようですが、分析の間違ったポイントでそれを試みていると思います。章の見出しは、常にページの上部にあり、常に中央に配置され、常にギャップが続くため、元のテキストで簡単に識別できます。これらの機能を使用すると、見出しを簡単かつ確実に識別できますが、この情報は、見出しを識別しようとする前に破棄されています。分析のこの段階を制御している場合は、代わりに、この段階で見出しとなっているエントリを特定する方が簡単です。
これを行うために正規表現は必要ありません
質問のタイトルでRegexを指定しますが、それは質問の本文には含まれていません。したがって、実際にはそれを必要とせず、不要な問題のRegexソリューションを探しているだけだと思います。
すべての大文字をテストする最も簡単な方法は、x == toupper(x)
を実行することです。 toupper()
は、すべてのアルファベット文字を大文字の形式に変換します。次に、この変換されたバージョンと比較して、文字列がすべて大文字かどうかをテストできます。
2未満の長さの文字列のスクリーニングも簡単です。nchar(x) >=2
条件を追加するだけでこれを実行できます。
最終的な要件はそれほど簡単ではありませんが、除外する必要がある条件を正確に把握する必要があります。完全な段落(?)を取得している場合は、引用符を探すことをお勧めします。一致させる必要のあるオプションの範囲によっては、結局、ここで正規表現を使用する必要があるかもしれませんが、それが特定のマークのみの場合は、_str_detect
_(stringr
パッケージから)をfixed()
これを検出するオプション。これはかなり高速になります。
この最終段階でRegexを使用するかどうかに関係なく、1つのRegex検索を実行するのではなく、関数内の一連の条件に検出をラップします。これにより、高速であり、概念的には理解が容易になると思います。
編集:
私は最初、小文字が2文字未満の場合は無視することを考えました。 allが大文字であることを確認したい場合は、wholeの長さが文字列は> = 2であり、はるかに単純な正規表現で実行できます。
^(?:[A-Z](?:[^A-Za-z\r\n])*){2,}$
デモ 。
または、長さが> = 2の文字列と一致させたい場合でも文字が1つだけ含まれている場合(たとえば、「A @」):
^(?=.{2})(?:[A-Z](?:[^A-Za-z\r\n])*)+$
別のデモ 。
元の答え:
正規表現のみのソリューションで、文字が> = 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,}
:前の文字と2回以上一致します。(?:
:2番目の非キャプチャグループの開始。[^A-Za-z\r\n]
:英語文字または行末記号ではない任意の文字に一致します。2|
:または。[A-Za-z]
:任意の英語文字に一致します。3(?!
:否定先読みの開始。[a-z]
:小文字の英語に一致します。4)
:否定先読みの終わり。)
:2番目の非キャプチャグループの終わり。*
:前のグループの0回以上一致します。)
:最初の非キャプチャグループの終わり。+
:前のグループと1回以上一致します。$
:行/文字列の終わりに位置をアサートします注:文字列全体を1行として扱うには、\r\n
部分。
[[:upper:]]
代わりに、英語以外の文字を照合する場合。[^[:alpha:]\r\n]
代わりに、英語以外の文字を照合する場合。[[:alpha:]]
代わりに、英語以外の文字を照合する場合。[[:lower:]]
代わりに、英語以外の文字を照合する場合。私がこれを理解する方法:
それで、私はこの正規表現で十分だと思います:
^(.|[^[: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
[〜#〜]編集[〜#〜]
文字列の文字数を処理するために、正規表現を変更せずに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
元の回答
最初に、アルファベット以外のすべての文字を空白( "")で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
私があなたの質問を正しく理解している場合は、次のような文字列を受け入れます。
それが正しければ、あなたは正解からほど遠くない。ただし、小文字以外の文字を受け入れる代わりに、大文字のみを受け入れます。
次の正規表現が機能するはずです。
^[^[:lower:]]{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