アプリ版:「スタンプのみでお礼する」機能のリリースについて

正規表現で以下の場合はどのようにすればよいのでしょうか?
条件)文字列は英数字と-は許すが文字列内のどこかに-が連続している場合はNGとする。

例)
abCd-012 ○
ABC--012 ×
A-B-C-D- ○

A 回答 (3件)

#2のように文字列全体とマッチする正規表現自体が必要なのではなく、


単に与えられた文字列が許されたものかNGかを知りたいだけであれば、
文字列が部分的にマッチするか否かで判定する方がずっと効率がいい。
この場合は#1の方が言っているように許されない-の連続があるかどうかが判断材料になる。

String[] strings = {"abCd-012", "ABC--012", "A-B-C-D-", "a_12#3", "-", "aBc9", "-A-B-C", "A-B-C", "--A"};
String regex = "[^-\\p{Alnum}]|--+";
Matcher matcher = Pattern.compile(regex).matcher("");
for (String s : strings) System.out.printf("%s %s%n", s, matcher.reset(s).find() ? "×" : "○");

正規表現 [^-\p{Alnum}]|--+ は、-または英数字以外の文字1個か([^-\p{Alnum}])、2個以上連続する-に(--+)マッチする。
判定したい文字列を与えたMatcherのfindメソッドでこのパターンにマッチする部分があるかないかを判断すればいい。
もちろん見つかればNGである。
    • good
    • 0

除外したい-の連続をどう表現しようかと考えると難しくなる。


単独の-でそれ以外の文字の塊が接続されていると考えるといい。

許される文字列の構造を考えてみるために、
Aを連続することが許された文字、
bを連続してはならない文字とする。
まず、1文字以上のAの連続(A+)や、単独のb(b)は許される。
そして、2つの A+ が1個の b で接続されているもの(A+bA+)も許される。
この場合、その文字列の先頭と末尾にbがあっても(無くても)構わない(b?)だろう。
これらのことから以下のようなものが許される文字列と考えられる。

b
b?A+b?
b?A+bA+b?
b?A+bA+bA+b?
b?A+bA+bA+bA+b?
...

最初の単独の b を除けば次のようにまとめられる。

b?A+(bA+)*b?

1個の A+ の後に bA+ が0個以上連続するパターンが一般形と考えられる。
単独の b のパターンを合わせると求めるべき正規表現は、

b|b?A+(bA+)*b?

質問では、

A = \p{Alnum}
b = -

なので、求める正規表現は、

-|-?\p{Alnum}+(-\p{Alnum}+)*-?

これしかないわけでなく考え方の問題なので別の表現もあると思うし、
一つの正規表現で一気に表現する必要が無ければもっと自由度が上がる。
この正規表現をプログラム中にリテラルとして書く場合は\をエスケープする必要がある。

String[] strings = {"abCd-012", "ABC--012", "A-B-C-D-", "a_12#3", "-", "aBc9", "-A-B-C", "A-B-C", "--A"};
String regex = "-|-?\\p{Alnum}+(-\\p{Alnum}+)*-?";
for (String s : strings) System.out.printf("%s %s%n", s, s.matches(regex) ? "○" : "×");
    • good
    • 0

-が連続して存在する場合にマッチするという条件でいいならば



-{2,}

でできると思います。
ちなみに-が2回以上続いていたらという表現です
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!