問題タブ [nested-reference]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - この正規表現はどのようにして三角数を見つけますか?
一連の教育正規表現記事の一部であり、ネストされた参照の概念を穏やかに紹介しています。
最初のいくつかの三角数は次のとおりです。
数値が三角形かどうかを確認する方法はたくさんあります。次のように正規表現を使用するこの興味深い手法があります。
- nが与えられると、最初に同じ文字で満たされた長さnの文字列を作成します
- 次に、この文字列をパターンと照合します
^(\1.|^.)+$
- このパターンが文字列と一致する場合にのみ、nは三角形になります
これがいくつかの言語で機能することを示すためのスニペットを次に示します。
PHP(ideone.com)
Java(ideone.com上)
C#(ideone.com)
したがって、この正規表現は機能しているように見えますが、誰かがその方法を説明できますか?
同様の質問
regex - a^nb^n をどのように一致させることができますか?
これは、一連の教育用正規表現記事の第 2 部です。先読みとネストされた参照を使用して、非正規言語 a n b nに一致させる方法を示しています。ネストされた参照が最初に導入されたのは、この正規表現は三角数をどのように見つけますか?
典型的な非正規言語の 1 つは次のとおりです。
L = { a
nb
n: n > 0 }
a
これは、いくつかの's とそれに続く同数の 's で構成されるすべての空でない文字列の言語ですb
。この言語の文字列の例はab
、、、aabb
ですaaabbb
。
この言語は、ポンピング補題によって非正則であることを示すことができます。それは実際、文脈自由文法によって生成できる原型的な文脈自由言語です。 S → aSb | ab
それにもかかわらず、現代の正規表現の実装は、通常の言語以上のものを明確に認識します。つまり、正式な言語理論の定義によると、それらは「規則的」ではありません。PCRE と Perl は再帰的な正規表現をサポートし、.NET はバランシング グループの定義をサポートします。後方参照マッチングなどの「派手な」機能でさえ、正規表現が規則的ではないことを意味します。
しかし、この「基本的な」機能はどれほど強力なのでしょうか? L
たとえば、Java 正規表現で認識できますか? ルックアラウンドとネストされた参照を組み合わせて、たとえば 、 、 などの文字列に一致するように機能するパターンを作成することはできますString.matches
か?ab
aabb
aaabbb
参考文献
- perlfaq6: Perl の正規表現を使用してバランスのとれたテキストに一致させることはできますか?
- MSDN - 正規表現言語要素 - グループ定義のバランス調整
- pcre.org - PCRE のマニュアルページ
- regular-expressions.info -ルックアラウンドとグループ化と後方参照
java.util.regex.Pattern
リンクされた質問
java - この Java 正規表現は回文をどのように検出しますか?
これは、一連の教育用正規表現記事の第 3 部です。この正規表現はどのように三角数を見つけますか? (ネストされた参照が最初に導入された場所)およびa^nb^n を Java 正規表現とどのように一致させることができますか? (先読み「カウント」メカニズムがさらに詳しく説明されています)。この部分では、入れ子になったアサーションの特定の形式を紹介します。これを入れ子になった参照と組み合わせると、ほとんどの人が「不可能」だと信じているものに Java 正規表現を一致させることができます: 回文!!
回文の言語は規則的ではありません。実際には文脈自由です (特定のアルファベットに対して)。とはいえ、最新の正規表現の実装は通常の言語以上のものを認識し、Perl/PCRE の再帰パターンと .NET のバランシング グループは回文を容易に認識できます (「関連する質問」を参照)。
ただし、Java の正規表現エンジンは、これらの「高度な」機能のいずれもサポートしていません。それでも、「誰か」( *wink* )は次の正規表現を書くことに成功しました。
これはうまくいくようですが、どうですか?
参考文献
コモンセンスアラート!!!
これは回文を検出する最良の方法ではありません。
O(N^3)
せいぜいです。より汎用的なプログラミング言語でこの検出を実行すると、より効率的で簡単になります。素数を見つけるために正規表現を使用したくないのと同じ理由で、回文を検出するために正規表現を使用したくないでしょう。そうは言っても、素数性のテストに正規表現を使用する方法を研究するのと同じ理由で、非再帰的非平衡グループ正規表現がどのように回文を検出できるかを研究します。それは楽しい、やりがいがある、教育的です。
関連する質問
- 正規表現を使用して文字列が回文であることを確認する方法は? - それは不可能だ"!(そうでもなければ...)
- 指定された文字列が回文かどうかを確認するには? - 多くの言語での非正規表現ソリューション
- 数値が正規表現で素数かどうかを判断する方法は?
c# - この正規表現の置換はどのように文字列を反転させますか?
これは、一連の教育正規表現記事の4番目の部分です。ネストされた参照(この正規表現は三角数をどのように見つけるか?)とアサーション内の「カウント」(参照:a ^ nb ^nをJava正規表現と一致させる方法)の組み合わせを使用して文字列を反転する方法を示します。 。プログラムで生成されたパターンは、メタパターンの抽象化を使用します(このJava正規表現はパリンドロームをどのように検出しますか?を参照してください)。シリーズで初めて、これらの手法は、文字列全体の照合ではなく、置換に使用されます。
完全に機能するJavaおよびC#の実装が提供されます。心に強く訴える引用が含まれています。
正規表現を使用して文字列を逆にすることは、決して良い考えとは思えませんでした。また、それが可能かどうか、もしそうなら、どのようにそうしようとするかはすぐにはわかりませんでした。
それはまだ良い考えではありませんが、少なくとも今ではそれが可能であることがわかっています。これを行う1つの方法があります。
C#(ideone.comにもあります)
Java (ideone.comにもあります)
C#バージョンとJavaバージョンはどちらも同じ全体的なアルゴリズムを使用しているようですが、抽象化された実装の詳細にわずかな違いがあります。
明らかに、これは文字列を逆にするための最良の、最も簡単で、最も効率的な方法ではありません。とはいえ、正規表現について学ぶために。パターンを概念化する方法。それらに一致するようにエンジンがどのように機能するか。さまざまなパーツを組み合わせて、必要なものを構築する方法。読みやすく、保守しやすい方法でこれを行う方法。そして、何か新しいことを学ぶという純粋な喜びのために、これがどのように機能するかについて説明してもらえますか?
付録:チートシート!
これは、使用される基本的な正規表現構造の簡単な説明です。
(?sx)
埋め込まれたフラグ修飾子です。s
「単一行」モードを有効にして、ドットを任意の文字(改行を含む)に一致させます。エスケープされていない空白が無視される(コメントに使用できる)フリースペースx
モードを有効にします。#
^
および$
は、行の先頭と末尾のアンカーです。?
繰り返し指定子はオプション(つまり、0または1)を示します。たとえば、繰り返しの数量詞として、 (つまり、ゼロ以上の)繰り返しが気が進まない/欲張りでない.*?
ことを示します。*
(…)
グループ化に使用されます。(?:…)
非キャプチャグループです。キャプチャグループは、一致する文字列を保存します。バック/フォワード/ネストされた参照(例\1
)、置換置換(例$2
)などが可能です。(?=…)
ポジティブな先読みです; 与えられたパターンの一致があると断言するのは右に見えます。(?<=…)
ポジティブな後ろ姿です; 左に見えます。
言語参照/追加リソース
java - Java 正規表現エンジンが + の繰り返しで StringIndexOutOfBoundsException をスローするのはなぜですか?
フィボナッチ数を見つけるための正規表現パターンを作成しました (理由は関係ありませんが、作成しただけです)。期待どおりに素晴らしく動作します ( ideone.com を参照):
このマッチング アルゴリズムで後戻りをしたくないため、所有格の繰り返し (つまり、メインの「ループ」) は非常に重要です。++
ただし、繰り返しをバックトラック可能にする (つまり+
、メインの「ループ」のみ) と、不一致ではなく、実行時例外が発生します!!! ( ideone.com で見られるように):
誰かがここで何が起こったのか説明できますか? これは Java 正規表現エンジンのバグですか?
php - このPCREパターンはどのようにパリンドロームを検出しますか?
この質問は、PCREのマニュアルページに記載されている再帰パターンでは一致しないパリンドロームを含む、すべてのパリンドロームに一致するPCREパターンでの先読み、ネストされた参照、および条件の使用法の教育的なデモンストレーションです。
PHPスニペットでこのPCREパターンを調べます。
このテストケースで見られるように、このパターンはパリンドロームを検出しているようです(ideone.comも参照)。
では、このパターンはどのように機能しますか?
ノート
このパターンはネストされた参照を使用します。これは、このJava正規表現がパリンドロームをどのように検出するかで使用されるのと同様の手法です。、ただし、そのJavaパターンとは異なり、後読みはありません(ただし、条件付きを使用します)。
また、PCREのマニュアルページには、いくつかのパリンドロームに一致する再帰的なパターンが示されていることに注意してください。
マニュアルページは、この再帰パターンがすべてのパリンドロームを検出できるわけではないことを警告しています(文字が2 n -1回繰り返された場合にのみこの再帰正規表現が一致するのはなぜですか?またideone.comを参照)が、ネストされた参照/ポジティブ先読みパターンが表示されますこの質問ではできます。
regex - 再演習: 階乗
これは、StackOverlow の実験的な新機能です。さまざまな古典的な問題を解決することで、正規表現の筋肉を鍛えます。正しい答えは 1 つではありません。実際、正しい答えが教育的価値を提供する限り、できるだけ多くの正しい答えを収集する必要があります。すべてのフレーバーが受け入れられますが、明確に文書化してください。できるだけ実用的なテストケース/スニペットを提供して、パターンが「機能する」ことを実証します。
正規表現を使用して、数値xが階乗であるかどうかをどのように確認できますか?
おまけ: パターンがx = nと判断できる場合! 、 nも見つけることができますか?