Perl正規表現で繰り返し文字を見つけるにはどうすればよいですか?
質問
繰り返し文字を見つける正規表現を探しています。そのため、たとえば2回以上の任意の文字:
booooooot or abbott
事前に探している手紙がわかりません。
これは、インタビューで尋ねられ、その後インタビューで尋ねられた質問です。それほど多くの人はそれを正しくしません。
解決
任意の文字を検索し、 \ 1
を使用して同じ文字を2回以上(またはそれ以上)検索します。文字を知る必要がある場合は、 $ 1
にその文字が含まれます。それ以外の場合は、2番目の一致を最初の一致に連結できます。
my $str = "Foooooobar";
$str =~ /(\w)(\1+)/;
print $1;
# prints 'o'
print $1 . $2;
# prints 'oooooo'
他のヒント
" \ w"ではなく、実際にこれが必要だと思います。数字とアンダースコアが含まれているため。
([a-zA-Z])\1+
わかりました、わかりました、レオンのヒントがあります。これをunicode-worldまたはposixのものに使用します。
([[:alpha:]])\1+
後方参照を使用するとうまくいくと思います:
(\w)\1+
\ w
は基本的に [a-zA-Z_0-9]
であるため、AとZの間の文字(大文字と小文字を区別しない)のみを一致させる場合は、 [a-zA-Z]
代わりに。
(編集:または、彼のコメントで言及されたTanktalusのように(および他の人も答えているように)、 [[:alpha:]]
、ロケール依存です)
前のグループを参照するには、\ Nを使用します。
/(\w)\1+/g
文字と見なされるものに注意する必要がある場合がありますが、これはロケールによって異なります。 ISO Latin-1を使用すると、アクセント付きの欧文文字を文字として照合できます。次のプログラムでは、デフォルトのロケールはéを認識しないため、 créé は一致しません。ロケール設定コードのコメントを外すと、一致し始めます。
また、\ wには数字とアンダースコア文字がすべての文字とともに含まれていることに注意してください。文字だけを取得するには、英数字以外の数字、アンダースコア文字を補完する必要があります。これにより、文字のみが残ります。
質問「"どの正規表現は3以外の数字に一致しますか?」
#! /usr/local/bin/perl
use strict;
use warnings;
# uncomment the following three lines:
# use locale;
# use POSIX;
# setlocale(LC_CTYPE, 'fr_FR.ISO8859-1');
while (<DATA>) {
chomp;
if (/([^\W_0-9])\1+/) {
print "文字と見なされるものに注意する必要がある場合がありますが、これはロケールによって異なります。 ISO Latin-1を使用すると、アクセント付きの欧文文字を文字として照合できます。次のプログラムでは、デフォルトのロケールは&#233;を認識しないため、 cr&#233;&#233; は一致しません。ロケール設定コードのコメントを外すと、一致し始めます。
また、\ wには数字とアンダースコア文字がすべての文字とともに含まれていることに注意してください。文字だけを取得するには、英数字以外の数字、アンダースコア文字を補完する必要があります。これにより、文字のみが残ります。
質問「&quot;どの正規表現は3以外の数字に一致しますか?」
<*>: dup [$1]\n";
}
else {
print "
文字と見なされるものに注意する必要がある場合がありますが、これはロケールによって異なります。 ISO Latin-1を使用すると、アクセント付きの欧文文字を文字として照合できます。次のプログラムでは、デフォルトのロケールは&#233;を認識しないため、 cr&#233;&#233; は一致しません。ロケール設定コードのコメントを外すと、一致し始めます。
また、\ wには数字とアンダースコア文字がすべての文字とともに含まれていることに注意してください。文字だけを取得するには、英数字以外の数字、アンダースコア文字を補完する必要があります。これにより、文字のみが残ります。
質問「&quot;どの正規表現は3以外の数字に一致しますか?」
<*>: nope\n";
}
}
__DATA__
100
food
créé
a::b
次のコードは、2回以上繰り返されるすべての文字を返します。
my $ str =&quot; SSSannnkaaarsss&quot ;;
print $ str =〜/(\ w)\ 1 + / g;
キックだけで、まったく異なるアプローチ:
if ( ($str ^ substr($str,1) ) =~ /\0+/ ) {
print "found ", substr($str, $-[0], <*>[0]-$-[0]+1), " at offset ", $-[0];
}
FYI、RegExBuddy以外に、正規表現をテストするための本当に便利な無料サイトは gskinner.comのRegExr 。 ([[:alpha:]])(\ 1 +)
を適切に処理します。
方法:
(\w)\1+
最初の部分は、文字の周りに名前のないグループを作成し、その後、後方参照はその同じ文字を探します。
これも機能するはずです:
((\ w)(?= \ 2))+ \ 2
/(.)\\1{2,}+/u
'u'修飾子とUnicodeとの一致