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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

6回答

2534閲覧

正規表現

mightyMask

総合スコア143

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2016/12/07 07:21

編集2016/12/07 08:41

#環境
以下の環境のjava言語を使用しています。
java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

質問の中では見やすい様にバックスラッシュを1つだけ記入していますが、javaの仕様上、本来のコードの中ではバックスラッシュを2つ重ねるか円マークを使用しています。

#質問
{*から始まり、*} で終わる文字列とマッチさせる処理についてです。

これだけなら\{\*.*\*\}の様に書くのが普通でしょうか。

これに改行も対応させたいです。
\{\*[\t-~]*\*\}の様に書けば出来たのですが、良い書き方なのでしょうか。

そして本題ですが、ネストに対応させたいです。
{* a {* b *} c *}
に対しては全てマッチし、
{* a {* b *}{* b *} c *}
に対しては
{*b*}
の部分だけマッチさせたいです。

色々試しましたが、何かうまくいきません。
再起的な処理になるので、正規表現だけでは無理があるのですかね。

#訂正
この括弧のルールだと、エスケープ文字が乱れてしまうので、ここでは
{*ではなく<,
*}ではなく>
の様な括弧の対応で考える事にします。

< a < b > c > には < a < b > c >
< a < b > には < b >
< < a > b には < a >
< a < b < c > > には < b < c > >
< a > b < c > には < a >< c >

のようになります。
<>の数が対応する条件で、一番外側の括弧とその中身がマッチするという様にしたいです。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikedas

2016/12/07 07:34

実際にお使いになっているプログラミング言語やプログラムを教えて下さい。正規表現には環境により違いがあることがあるので。
kunai

2016/12/07 07:35

正規表現と一言で言っても、使う環境によって書き方が変わってきます。想定されているプログラム言語なりツールを教えていただけますか?
guest

回答6

0

ベストアンサー

お察しの通り、任意の深さの括弧の入れ子を、正規表現だけで扱うことはできません。

しかし、実用上は、入れ子がある深さ以下の場合しか入力に現れないことも多いです (またはそう仮定して、想定外の深い入れ子のときはあきらめる)。とにかくその場合は、入れ子が1、2、……最大値の表現を作って、それを選言 (|) で連結すれば、目的の正規表現ができますね。

<[^>]*<[^>]*<[^>]*>[^>]*>[^>]*> # 3重 <[^>]*<[^>]*>[^>]*> # 2重 <[^>]*> # 1重 だから3重以下は <[^>]*<[^>]*<[^>]*>[^>]*>[^>]*>|<[^>]*<[^>]*>[^>]*>|<[^>]*>

とはいえ、入れ子が深くなるほど正規表現は複雑になっていくので、深さが小さくないのなら正規表現を使わないほうがいいと思います。

  • Scannerを使えばテキストをトークンに分解して解析できます。
  • 本格的な構文解析が必要ならJavaCCも使えます。

投稿2016/12/07 08:47

ikedas

総合スコア4317

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikedas

2016/12/07 09:05 編集

自作インタプリタでコメントの解析に使うとのことですが、であれば「コメントはネストできない」と決める、という手もあります。あるいは、「"{*" が何回出現しようと、"*}"が出現したらコメントは終了」でもいいでしょう。
raccy

2016/12/07 09:38

私もネスト禁止に一票です。むしろコメントをネストできる方が少ない(Cの/*...*/は無理、HTMLの<!--...-->も無理等)ので、無理にネストを実装しない方が良いかと思います。
guest

0

HTMLなどのタグがイメージとして近い気がしますが合っていますか?

もしそうでしたら、正規表現だけだと無理だと思います。

正規表現は、予め決められたパターンに一致するかどうかを判定するものなので、
開始タグはあるけど閉じタグがないものやその逆を判断するには適していないと思います。

正規表現よりは構文解析について調べると良いと思います。

投稿2016/12/07 08:44

ijufumi

総合スコア276

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

実際にやりたいことは字句解析ってところですかね?
そうなるとトークン使ってどうこうって話になると思います。
簡単な実装例

追記
こっちの方はやりたいことにかなり近そうだったので
パーサーの作り方

投稿2016/12/07 08:33

編集2016/12/07 08:42
ishi9

総合スコア1294

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mightyMask

2016/12/07 08:47

はい。その通りです。自作言語のインタプリタを作りたくて、その字句解析を作成しています。 この辺りの記事も既に目に通しています。 今やろうとしているのはコメントの処理なので、できればトークンにせず処理したいのです。
guest

0

正規表現テスト

こんなサイトが色々あります。
試行錯誤してみては?

投稿2016/12/07 08:03

mugicya

総合スコア1046

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

1階層を仮定すると
<[^<>]>
2階層以下を仮定すると
<[^<>]
(?:<[^<>]>[^<>])>
3階層以下を仮定すると
<[^<>]
(?:<[^<>](?:<[^<>]>[^<>])>[^<>])>

というようにある有限階層以下を仮定しない限り、正規表現は無限の長さになります。
その前に正規表現コンパイラが音を上げます。

文脈自由文法では、無限階層でも、有限の規則で極めて簡素に書けます。
Javaの構文規則も文脈自由文法で書かれています。
文脈自由文法は、正規表現より1ランク上の複雑な構造を扱えるのですが、まともに実装すると非常に骨が折れます。

現実的には、'<'で階層を1つ下げ'>'で1つ上げるカウンタ方式か、最難でもスタック方式でしょうね。

投稿2016/12/07 11:54

naomi3

総合スコア1105

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

\{\*([^\{\*]*)\*\}

こんなのでどうでしょうか。

投稿2016/12/07 07:48

kunai

総合スコア5405

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mightyMask

2016/12/07 07:59

この書き方だと、{* と *} の間に {* が来ないものを表していますから、一番内側の括弧とその中身とマッチする形になっている様です。 そうではなく、一番外側の括弧とその中身とマッチする様にしたいのです。
kunai

2016/12/07 08:07

一番外側の{* *}と言う事だと、{* a {* b *}が「b」だけ抽出する理由がよくわからないのですが。。 質問文に、「この文字の場合」「コレを抽出したい」と言う例を具体的に示していただけますか?
kunai

2016/12/07 08:50

仕様に一貫性がないので無理だと思います。 < a < b > c >の場合は「一番外側の< >」であり、 < a < b >の場合は「一番内側の< >」がマッチするというような形で 仕様が異なるため、少なくとも1つの正規表現で取得するのはムリだと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問