質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.19%

正規表現 | 〜〜のみ含むパターンと、〜〜は含んではいけないパターン (続編)

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 831
退会済みユーザー

退会済みユーザー

前回、質問内容に漏れがあり再現することができませんでした。
https://teratail.com/questions/239924

行いたい正規表現は以下の通りで試行錯誤しているのですが、うまくいかないので教えていただきたいです。

文字列 期待値
漢字 OK
カタカナ OK
漢字カタカナ OK
あ漢字カタカナ NG
漢字あカタカナ NG
漢字カタカナあ NG
半角スペース 期待値
 漢字カタカナ NG
  漢字カタカナ NG
漢字 カタカナ OK
漢字  カタカナ NG
漢字 カ タカナ OK
漢字 カ  タカナ NG
漢字カタカナ  NG
漢字カタカナ   NG
全角スペース 期待値
 漢字カタカナ NG
  漢字カタカナ NG
漢字 カタカナ OK
漢字  カタカナ NG
漢字 カ タカナ OK
漢字  カ  タカナ NG
漢字カタカナ  NG
漢字カタカナ   NG

基本的な許容文字形式に加え、文字列の間にあるスペースは1つまでとしたいのです。

追記

細かいところは以下のように定めたいと思います。

要件

漢字とカタカナの入力を許容し、
全角ハイフン(長音)と全角スペースと半角スペースも許容するが
全角ハイフン(長音)と全角スペースと半角スペースについては連続で1文字までしか入力できないものとする。

漢字の取り扱い

  • ここでいう漢字とは、全角で1文字を表すものとする。
  • ㍻などのような環境依存文字は漢字と見做さない。
  • 吉野家などのようなのような文字列でも人間が見て全角で1文字を表す漢字だと判断できるものは漢字と見做す。

カタカナの取り扱い

  • ここでいうカタカナとは、全角で1文字を表すものとし、以下のみをカタカナとして取り扱う。

清音
アイウエオ
カキクケコ
サシスセソ
タチツテト
ナニヌネノ
ハヒフヘホ
マミムメモ
ヤユヨ
ラリルレロ
ワヰヱヲ

濁音
ガギグゲゴ
ザジズゼゾ
ダヂヅデド
バビブベボ

半濁音
パピプペポ

その他

ァィゥェォ
ヵヶッ
ャュョ


以下は漢字で変換できるためカタカナとは認めない。(漢字とするかカタカナとするか悩ましい)
ヵヶ

スペースの取り扱い

  • 文頭の全角及び半角スペースは許容しない。
  • 文末の全角及び半角スペースは許容しない。
  • 文中の全角及び半角スペースは2文字連続に限り許容しないが、1文字でづつであれば文中何度出現しても許容する。

※以下に例を示すが、全角スペースも同様の扱いとする。

テスト文字列   期待値  
漢字 カタカナ    OK 
漢字  カタカナ    NG 
漢字 カ タカナ    OK 
漢字 カ  タカナ    NG 
漢 字 カ タ カ ナ    OK 
漢 字 カ タ カ  ナ    NG 

全角ハイフン(長音)の取り扱い

  • 文中の全角ハイフン(長音)は2文字連続に限り許容しないが、1文字でづつであれば文中何度出現しても許容する。
  • 全角ハイフン(長音)はカタカナとして表現できる文中にしか存在してはならず、カタカナの文頭には含んではならないが文末には含むことができる。
  • 長音はひらがなかカタカナまでは区別する必要はなく、人間が全角ハイフンだとわかれば良い(ここは、あえて曖昧さを残す)
テスト文字列   期待値  
漢ー字ギータ    NG 
漢字ギータ    OK 
漢字ギーター    OK 
漢字ギーーター    NG 
漢字ギター    OK 
漢字ーギター    NG 
漢字ギータ    OK 
ギーター漢ー字    NG 
ギーター漢字    OK 
ギーーター漢字    NG 
ギター漢字    OK 
ーギター漢字    NG 

検証方法

カスタムルールとしてグローバルに使いまわしたいため、以下の形式のコードでtest関数を用いてチェックするものとする。

const pattern = /^([ァ-ン一-龥][  ]?)*(((([ァ-ン]|ー)[  ]?)*([ァ-ン]|ー))|[一-龥])$/
console.log(pattern.test(value))

--- 

正規表現でここまで苦戦するとは思ってなかったので、連続スペースとかハイフンかと、もうサーバー側で修正した方が早いかも。
フロント側でもきっちりやりたいのは単なる自己満なので。。。
なんだか手を出しちゃいけないものにハマっていってる気がする。

最終追記

既存の一致項目に影響がないまま、項33~43までの期待値と結果が一致することで良しとしたいと思います。
https://codepen.io/postman_tyo/pen/vYOOLNL

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Zuishin

    2020/02/11 00:48

    漢字の定義がなされてないのに「漢字一文字を漢字とする」というのは無意味。何度も言ったけど。

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2020/02/11 00:48 編集

    なるほど、それはごもっともです。
    そしたら、プログラムがどうやって漢字であるかを判定しているのか、そういうコアな部分から知っていかないとこの問題は解決しそうにないですね。
    しかし、そこまで時間をさくわけにはいかないので、別のアプローチを考えます。

    キャンセル

  • 退会済みユーザー

    2020/02/11 11:06

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 2

+5

漏れがあったのは要件が正確ではなく、曖昧な部分があるからです。厳格な要件を定めるところから始めなければなりません。

要件

  • HTML5のinput要素におけるpattern属性に使用し、入力値のチェックに使用する。
  • 対応ブラウザはPC環境のみターゲットとし、最新のGoogle Chrome、Chromium版Microsoft Edge、Apple Saffariとする。その他のブラウザは考慮しない。
  • 漢字とカタカナのみで構成される場合のみマッチする。
  • 漢字はScriptプロパティがHanであるUnicode文字とする。
  • Hanには、JIS未登録の日本では使用されない漢字も含まれる。
  • Hanには、(U+337B)のような漢字を使用したCJK互換用文字は含まれない。
  • カタカナはScriptプロパティがKatakanaであるUnicode文字と長音記号(U+30FC)とする。
  • Katakanaには、(U+31F0)等の片仮名拡張や(U+FF71)等の半角・全角形の半角片仮名、(U+3300)等の片仮名のみで構成されたCJK互換用文字が含まれる。(他にもあるかも知れない)
  • Katakanaには、片仮名体系にあると言った記号や、と言った濁点・半濁点は含まれない。
  • 例外として、漢字またはカタカナの間に スペース(U+0020)または 和字間隔(U+3000)のどちらか一つだけがあっても良い。
  • スペースと和字間隔は、両方が連続してあってはならない。
  • スペースと和字間隔は、連続して二つ以上あってはならない。
  • スペースと和字間隔は、漢字と漢字、カタカナとカタカナ、漢字とカタカナおよびその逆の間であっても良い。
  • 合字や結合文字は考慮せず、コードポイント単位で判断する。(U+30F4)はカタカナとするがヴ(U+30A6 U+3099)はカタカナとはしない。
  • UTF-16ではサロゲートペアになってしまう文字であっても、一つのコードポイントとして判定する。
  • 空文字列はpatternでのチェックが行われないが、マッチはさせない。
  • 対応するUnicodeのバージョンはブラウザの実装に依存とする。
  • 正規表現はASCII文字のみを使用して表現する。

正規表現

(\p{Script=Han}|\p{Script=Katakana}|\u30FC)+([ \u3000](\p{Script=Han}|\p{Script=Katakana}|\u30FC)+)*

Google Chrome 80.0.3987.87 でのみ確認しています。その他のブラウザでは確認していませんが、Chromium版Microsoft Edge、Apple Saffariでも動作すると思われます。

確認用HTML

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>確認用</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
    <script type="module">
      const form = document.getElementById('form');
      const inputText = document.getElementById('inputText');
      inputText.addEventListener('input', () => {
        if (inputText.value) {
          form.classList.add('was-validated');
        } else {
          form.classList.remove('was-validated');
        }
      });
    </script>
  </head>
  <body>
    <div class="container-fluid mt-2 mx-2">
      <form id="form">
        <div class="form-group row">
          <label for="inputText" class="col-sm-2 col-form-label">テキスト入力</label>
          <div class="col-sm-8">
            <input id="inputText" class="form-control" type="text" pattern="(\p{Script=Han}|\p{Script=Katakana}|\u30FC)+([ \u3000](\p{Script=Han}|\p{Script=Katakana}|\u30FC)+)*">
            <div class="valid-feedback">
              OK
            </div>
            <div class="invalid-feedback">
              NG
            </div>
          <div>
        </div>
      </form>
    </div>
  </body>
</html>

私が書いた要件と期待しているものが異なるというのであれば、上に書いた要件のように厳格な要件を質問に追記してください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/10 23:44

    Unicode文字やU+30FCなど細かいところは分かりませんが、要件として定めました。

    キャンセル

  • 2020/02/11 01:58

    「𠮷野家」と「吉野家」は同じようで違うのですね。
    最終的に考えましたが、こういうのは捨てます。

    吉野家で手入力したら普通に、漢字として拾ってくれるので、そういうマイナーなことするユーザーは考慮しません。


    提示していますcodepenの、既存の一致項目に影響がないまま、項33~43までの期待値と結果が一致することで良しとしたいと思います。

    キャンセル

  • 2020/02/11 13:36

    質問の要件にはまだ曖昧さが残っていると私は考えているのでこれ以上回答はしませんが、満足したものができたのであれば、それを回答して自己解決して、質問を閉じてください。

    キャンセル

+2

こんにちは

以下でどうでしょう?

const regexp = /^([一-龥][  ]?)*(((([ァ-ン]|ー)[  ]?)*([ァ-ン]|ー))|[一-龥])$/

上記の正規表現で、ご質問にある各文字列をテストするコードを作成して、以下に上げておきました。

以下で、試すことができると思います。

  • git clone https://github.com/jun68ykt/q240432.git
  • cd q240432
  • yarn install
  • yarn test

以下は、上記の手順を私の手元のターミナルで行ったときのキャプチャです。

イメージ説明

以上、参考になれば幸いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/10 14:54

    ご提示いただきありがとうございます。
    パターンはいくつか挙げていますが、
    「基本的な許容文字形式に加え、文字列の間にあるスペースは1つまでとしたい」
    がやりたいことなので以下がNGになってしまいます。

    `カタカナ漢字`

    「漢字とカタカナに加え、文字列の間にあるスペースは1つまでとしたい」
    としたときの正規表現はできないのですかね。。。

    キャンセル

  • 2020/02/10 15:10

    以下で実現できましたが1つ1つ理解したいのでお付き合いいただけると助かります。
    /^([ァ-ン一-龥][  ]?)*(((([ァ-ン]|ー)[  ]?)*([ァ-ン]|ー))|[一-龥])$/

    ^はマニュアル通り分かります。
    ・先頭の文字列はカタカナもしくは漢字でなければならない
    ^([ァ-ン一-龥][  ]?)*の部分ですね。

    ただ、なぜ^([ァ-ン一-龥  ]?)*のようにまとめられないのかが分かりません。

    最後の$は文末ということはわかるのですが、
    (((([ァ-ン]|ー)[  ]?)*([ァ-ン]|ー))|[一-龥])
    の部分の分け方がどうなっているのかが分かりません。

    要望を日本語で説明すると、
    文字列の間にあるスペースは1つまでとしたいなので
    その部分が(([ァ-ン]|ー)[  ]?)なのかと推測はできますが、
    「文字列の間にある」という部分に(([ァ-ン]|ー)[  ]?)があり、
    この部分だけ見ると私の理解では
    「文中にマッチできるのはカタカナか全角ハイフンか両スペースが1つであり」
    というふうに読めるのですが、
    なぜ両スペースだけではなく、カタカナと全角ハイフンの記載をしているのかがわからないです。

    キャンセル

  • 2020/02/11 15:00

    こんにちは

    私の回答は、ご質問にある「追記」より前の表に書かれている文字列と期待値の組を満たす正規表現の一例を回答したに過ぎませんが、その後、POSTMAN様が他の回答者様と詳細を議論されている内容を拝読し、また「追記」の後に書かれている、さらなる要件を拝読いたしますと、私の回答はPOSTMAN様が回答に期待されている要件のほんの一部ということが分かりました。

    さはさりながら、私としては回答したことが無駄になったとは全く思っておりません。むしろ、回答した正規表現を作るにあたって、頭の体操として純粋に愉しませて頂きました。誠にありがとうございました。

    コメントを拝読いたしますと自力で解決なさったようで、お慶び申し上げます。正規表現に関して大変高い技術力をお持ちの方とお見受けしまして、私のほうがPOSTMAN先生からご指導賜りたいぐらいです。

    暦の上では春ですが、まだまだ余寒厳しい日々がつづきます。 風邪などひかれないようくれぐれもご自愛ください。
    草々

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.19%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる