見出し画像

正規表現の「後方参照」は誤訳であり、その誤訳が学習者の理解を妨げていると抗議します。 誰に?

正規表現って、便利ですよね。
検索条件がちょっと複雑で、あるパターンに合う文字列を探そうというとき、正規表現を使います。
一般的な、検索文字列にワイルドカード、アンドやオアを使った検索で、どんなに頑張っても無理なことがありますよね。そんなときに正規表現を使えば、答え一発的に結果が出ます。業務効率が段違いにアップすること間違いなしです。
私は、正規表現を覚えて、人生が変わったと思っています。

さて、正規表現には後方参照という仕組みがあります。

知っている人には、釈迦に説法というやつになりますかね。

英語では、backreference。

私は、正規表現を学ぼうとして、この後方参照という用語の意味がすんなり入ってこなくて、使い方を理解するのに苦労しました。

ネットで調べた限りでは、理解して書いているようでもなく、ましてわかるように説明している日本人は、見つかりませんでした。書いている人が私と似たようなレベルの人ばかりなのかもしれません。
ネットで調べる限界を感じました。また、日本人はダメだと思いました。
そこで英語の説明を読みました。

後方参照って何?

後方参照について混乱しているとき、ネットで調べて導き出した答えがこちらです。

正規表現における丸括弧は、それに囲まれた文字列や正規表現をグループ化する。
グループ化されたパターンにマッチしたものは、backreference として store される。
そして、store された backreference は、正規表現の中で再利用したり、後から再利用したりできる。

答えというか、英語の説明を要約した程度のものです。
ただし、日本語にすると意味がわからなくなってしまうので、大事なところは英語のままにしてあります。

正規表現についての説明へのリンクを貼ります。

私は、これを読んで正規表現や後方参照を理解しました。

余談ですが、Make a Donation と言っています。

Did this website just save you a trip to the bookstore? Please make a donation to support this site, and you'll get a lifetime of advertisement-free access to this site!

Backreference について、次のように説明しています。

Within the regular expression, you can use the backreference \1 to match the same text that was matched by the capturing group. ([abc])=\1 matches a=a, b=b, and c=c. It does not match anything else. If your regex has multiple capturing groups, they are numbered counting their opening parentheses from left to right.

英語を読んで理解したと言いましたが、この説明はわかりにくいですね。

補足しながら訳してみます。

正規表現の中では、後方参照 \1 を使用して、捕獲グループにマッチしたテキスト(そのもの)を使って、(それ以降のテキストがそれにマッチするかを)評価することができます。([abc])=\1(という文)は、a=a, b=b, c=c(のうちのどれか)にマッチします。それ以外のものにはマッチしません。正規表現に複数の捕獲グループがある場合は、それらのグループは、その開始括弧を左から右に数えて番号が付けられます。

訳が下手なせいか、結局わかりませんよね。
capturing group を捕獲グループと訳しましたが、英語のままでも意味はわかります。

([abc])=\1 について説明を試みます。

[abc] は、a、b、c のどれか1文字にマッチするかを評価する文です。
a にマッチしたら a、b にマッチしたら b、c にマッチしたらc ということです。
([abc]) のように丸括弧で囲むと、1つのキャプチャリンググループ*を定義します。
*一般に、グループと呼ばれています。グループにはいくつか使い道があって、全てを説明している日本人がいないのも、混乱を招きます。
マッチした文字列は、後で参照するために保管しておきます。どこかに。
= はそのままイコールという文字です。
数式のイコールに見えて混乱しますね。正規表現は、数式や条件式ではなく文なので、= は当号ではなく、単なる文字を表します。
末尾の、\1 が後方参照です。
最初の ([abc]) という文で文字列を評価したときにマッチした文字を表します。その文字列は、前にどこかに保管した文字列です。
\1 が登場したら、そのどこかに保管した文字列を確認しにいきます。そして、その文字列にマッチするかを評価するのです。

私は、「後で参照するために保管しておきます。」と言いました。
これが まさにbackreference の意味です。
backreference は、その補完したテキストを指していると思います。

後方参照と聞くと、後方を参照すると思ってしまいます(私はそういう意味だと思ってしまいました)が、そのように解釈してしまうと理解を妨げることになります。

文字列の後方と言われたら、末尾の方向を想像しませんか。人によっては、反対の方向かもしれませんが。
しかし、backreference のback は、そういう位置の前後ではないのです。というか、ではないはずです。そう考えないと、理解できません。

英単語と和単語とは1対1で対応していません。使い方で、同じ意味にもなりますし、意味が違ってくる場合もあるのです。
私は、back を後方と訳した人に言いたいのです。間違ってますよ、と。

余談ですが、英語を日本語に翻訳する場合、英単語のイメージを理解すればより良い翻訳ができると思っています。
単語のイメージを学ぶと良いです。
でも、そこまでしなくても、辞書を引いたら、書いてあること全てを吟味したら良いと思います。全部の意味を見たら、その単語のイメージが湧いてくるのではないでしょうか。そのイメージを元にして、文脈に相応しい日本語を選べば良いと思います。辞書には限られた意味しか載っていません。イメージが掴めたら、それ以外の単語を使って適切な日本語に変換できるかもしれません。もしかしたら、単語を1個1個訳すことなく、文全体の意味が見えてくるかもしれません。
何か参考になるものはないかと検索したら、コアイメージ批判がヒットしました。いや、違うでしょと思いましたね。日本語から変換する前提で、コアイメージを批判していました。全然わかってない。コアイメージを頭に叩き込んだら、英語で考えたら良いのです。直、英語で書いたり話したりする。それくらいできるようになりませんか。日本語で考えてから英語にするなんて、無駄じゃないですか。ナンセンスだと思います。
英語の上級者は、英語で考えるって言いますよね。私はまだできませんが。

t.koba のつぶやき

back を辞書で調べてみます。

この back という単語、たくさんの意味を持っています。
副詞なら「後方へ」が最初に出てきます。でも、副詞ではないでしょう。
名詞か形容詞かなと思います。
名詞の意味は「背」です。
形容詞なら、「後ろにある」とか「逆行する」と言った意味があります。
また、副詞の場合には、興味深い意味がありました。「さかのぼって」とか「過去に」です。

reference についてはどうでしょうか。
名詞、「言及」や「参照」がありました。どちらも、行為を表す名詞に思えます。しかし、これらを当てはめてみてもしっくり来ませんよね。

英語の正規表現の説明を読んで、store という単語が使われていました。
そこで考えたのですが、reference の意味は、そこで store したテキスト、参照すべきもの、つまりリファレンスと考えるのが適切ではないかと思います。

バックリファレンスとは、前に保存したリファレンスとすべきテキストということだと思います。
リファレンスとすべきと言いましたが、参照すべきということです。

back は後方ではない。
reference も参照ではない。

「後方参照」は誤訳と考えます。

英語のセンスのないエンジニアや研究者が、辞書を引いて適当に日本語を当てはめたと思われるケースは、他にもあります*。

*今、パッと出てくるものはありません。

そのようないい加減な翻訳が、学習者の理解を妨げる可能性があることを、認識してもらいたいと、強く訴えたいと思います。

以上です。

t.koba


以下は、参考

ここから下は、この記事を書くにあたって私が呟いたことです。

バックリファレンスは、キャプチャーグループによって以前にマッチしたのと同じテキストにマッチする。

ここでバックリファレンスの品詞は名詞であり、主語として使われている。

Backreference について詳しくは↓

https://www.regular-expressions.info/backref.html

Group 化について

Place parentheses around multiple tokens to group them together. You can then apply a quantifier to the group. E.g. Set(Value)? matches Set or SetValue.

Parentheses create a capturing group. The above example has one group. After the match, group number one contains nothing if Set was matched. It contains Value if SetValue was matched. How to access the group’s contents depends on the software or programming language you’re using. Group zero always contains the entire regex match.

Use the special syntax Set(?:Value)? to group tokens without creating a capturing group. This is more efficient if you don’t plan to use the group’s contents. Do not confuse the question mark in the non-capturing group syntax with the quantifier.

Group 化について詳しくは↓


英語を読む限りにおいて、ま、俺が読んだ限りにおいて、バックリファレンスするといった、つまり後方を参照するといったことを言っているところは見当たらなかった。

ま、勝手に沢山引用すると著者が困ると思うので、このくらいで、、、続きを読んで、可能なら寄付してもらえればと思う。知りあいでもなんでもないけど、そう思う。

ざっくり眺めたところでは、大抵、「グループ化できる」みたいに書いてある。

グループ化って何?

読んでもよく分からないので、混乱する。書いている人たちも、グループ化の意味を理解しているのだろうか。

どうやら、単にまとめて扱うために使うと考えている人が一定数いそうな感じだった。こんな使い方↓。

( 1 + 2 ) × 3 

$1, $2 と書いている人はわかっている人のようだ。俺が知りたいことを書いてくれているが、残念ながら、言語が違うので解釈が必要になる。LibreOffice に持ってくるには、どう翻訳したら良いのだろうか。

あと、検索後に再利用できるとしている人がいる。何を言っているかわからない。

「正規表現のグループ化。括弧の中の正規表現にマッチした文字列は後方参照 のために記憶されます。」と書いてあった。俺が正規表現を拒否した理由の一つがこの「後方参照」という用語だった気がする。

意味がわからない。

グループについて調べる。

グループ分けとして、group(n)でn番目のグループにマッチした文字列を参照できると書いているサイトがあった。Java について書いたものではないかと思う。LibreOffice で group(n) は使えない。

で、パクったコードと同じように正規表現に丸括弧を使っているサイトをよく読んで、グループ化の意味に気づいたのだった。

しかし、後方参照についてはまだ納得がいかない。これまでに述べたグループ化では、理解できない話だ。

Python のドキュメントがあった。

Regular Expression Syntax

(...)
Matches whatever regular expression is inside the parentheses, and indicates the start and end of a group; the contents of a group can be retrieved after a match has been performed, and can be matched later in the string with the \number special sequence, described below. To match the literals '(' or ')', use \( or \), or enclose them inside a character class: [(], [)].

(....)は、括弧の中にある正規表現にマッチし、グループの開始と終了を示します。グループの内容は、マッチが実行された後に取得することができ、後述する\number特殊シーケンスで文字列の中で後からマッチさせることができます。リテラル '(' or ')' にマッチさせるには、'(' or ')' を使用するか、文字クラスの中で囲んで下さい。[(], [)].

辞書を引いてみる。

Backreference in dictionary

Noun
(computing) An item in a regular expression equivalent to the text matched by an earlier pattern in the expression.
Verb
(computing) To access (the text matched by an earlier pattern in a regular expression).

名詞
(計算) 正規表現内の項目で、表現内の以前のパターンによってマッチしたテキストと同等のもの。
動詞
(コンピューティング)アクセスすること(正規表現の以前のパターンでマッチしたテキスト)。

まとめ

backreference は、ストレージ領域を指している?

要するに、正規表現の式は左から評価されていき、最初のグループにマッチした文字列は1番に記憶される。そしてそれを式の後の方で利用することができる(後方参照)。さらに検索が終わった後もそれは保持されているので1番を指定すれば抽出することができる(事後参照とか?)、といった感じだろうか。

結局、後方参照について出鱈目な説明が多くて、理解を妨げているということがわかった。


俺もそう思った。

どうも後方参照の「後方」が方向を表す語であると考えるのが間違いらしい。

Back は 後方ではなく、前に戻るという意味だろうと思うのだ。

もう一度辞書に書いてあったことを読み直してみる。

マッチしたテキストと同等のもの

と書いてあった。後方参照という意味はない。また、動詞もあるようだが、それも後方とは言わず以前のと言っている。

和英辞書

Backreference ではなく、refer back で検索。refer back to で

[文書において前述の] 〜を参照する、とあった。

これだ。

このバックに違いない。

前でマッチしたテキストを参照する。

後退参照、逆行参照、逆戻参照、後戻参照、

違うな。いらんなあ。back とか。そもそもこれがダメか。

back じゃなくて、先にマッチしたテキストという意味だろう。


Stored in backreference

The part of input string matching the capturing group is stored in a "backreference" for late recall.

このようにバックリファレンスが形のあるもの(形式名詞ではないという意味で)として扱われているならば、reference は参照するためのデータであるだろうから、back というのは先にマッチした結果を遡って参照するという意味ではないかと思う。

だから backreference の back は後方を意味しないと思う。

物事の理解は、用語からと思っている。何か勘違いするような用語をつけてまったら説明に時間が取られるし、学習する側も用語と中身の不一致から余計に記憶する努力を要することになるに違いない。

調べていくと、どうやら backreference とは、行為とか動作ではなく、ものを指している。back で 参照するものらしい。

つまり、後方を参照するでもなければ、後方で参照するでもない、ということだ。


Besides grouping part of a regular expression together, round brackets also create a “backreference”. A backreference stores the part of the string matched by the part of the regular expression inside the parentheses.

正規表現の一部をグループ化するだけでなく、丸括弧は「後方参照」を作成します。後方参照は、正規表現の部分にマッチした文字列の部分を括弧の中に格納します。



この議論の中で、「詳説正規表現」の第2版の訳注に言及しているが、そのとおりと思う。

現状では、backreference を後方参照と訳すしかないと思う。勝手に前方参照というのは間違っている。参照する方向を示していないのだから、

Forward = 文を後ろの方向へ
Backward = 文を前の方向へ

これは合っていると思う。しかし、back は向きを言っていないようなので、これを引き合いに出すのは話がずれた方向に向かってしまう。

back はやはり前に戻るという意味だろうと思う。しかし、今更用語を変えることはできないだろう。

誤解を防ぐ用語に直すとしたら、バックリファレンスとするか。

t.koba

この記事が気に入ったらサポートをしてみませんか?