91733
# 環境

  * Visual Studio Code 1.71.0

[![画像の説明をここに入力](https://i.stack.imgur.com/o30rz.png)](https://i.stack.imgur.com/o30rz.png)

# やりたいこと

VSCodeの検索/置換ウィジェットで正規表現を利用したいです。  
正規表現は実装によってばらつきがあるので、どのような正規表現が利用できるのかを知りたいです。  
たとえば`\w`はASCII文字以外の`あ`などにもマッチするかなどです。

# 質問

VSCodeの検索/置換ウィジェットで正規表現エンジンは何でしょうか？

<https://stackoverflow.com/questions/42179046/what-flavor-of-regex-does-
visual-studio-code-use> には以下のような回答がありました。

> JavaScript Regex in the Find/Replace in File Widget  
>  Alexandru Dima of MSFT wrote that the find widget uses JavaScript regex. As
> Wicktor commented, ECMAScript 5's documentation describes the syntax. So
> does the MDN JavaScript Regular Expression Guide.

JavaScript Engineを利用しているようです。  
ただし、この回答は2016年のGithub Issueでの回答を参照しています。  
2022年のVisual Studio Codeでも同じなのかが知りたいです。

[![画像の説明をここに入力](https://i.stack.imgur.com/WUeCE.png)](https://i.stack.imgur.com/WUeCE.png)
CC BY-SA 4.0
2022-10-21T03:23:51.297
91714
2022-10-22T07:16:36.863
2022-10-22T06:36:30.397
19524
19524
question
正規表現 vscode
VSCode 1.71.0での検索/置換ウィジェットで利用できる正規表現エンジンは何ですか？
以下は、VSCode 1.72.2 で検証しました。今後のバージョンアップによって動作が変更になる可能性がありますので、ご注意ください。

簡単に言うと、エディターで開いているファイルはV8の正規表現エンジンがそのまま使用されているようですが、エディターで **開いていない**
ファイルの検索は[ripgrep](https://github.com/BurntSushi/ripgrep)を使用しています。詳しく見ていきます。

## 開いているファイルの検索の動作

こちらはソースコードを細かく追っかけたわけではないのですが、JavaScript特有の動作をしているため、V8(Chromium側がNode.js側かまでは不明、両方の可能性有り)の正規表現エンジンをそのまま使用していると考えられます。

根拠は`\s`がU+FEFFに引っかかるためです(BOMである先頭のU+FEFFは除く)。ECMAScriptの正規表現の`\s`は`[
\f\n\r\t\v​\u00a0\u1680​\u180e\u2000​-\u200a​\u2028\u2029\u202f\u205f​\u3000\ufeff]`と同等であり、U+FEFFが含まれるかなり珍しい正規表現エンジンです。他の多くの正規表現エンジンでは、`\s`に`[
\t\r\n\f\v]`以外にもUnicode拡張として`[\p{White_Space}]`(Rust)や`[\p{Z}]`(.NET)やそれらを参考にした独自のリスト(Perl?)がありますが、U+FEFFはUnicodeのZカテゴリーにもWhite_Spaceプロパティにも含まれないため、(私が知る限り)`\s`に含まれる正規表現エンジンはありません。

これは「検索」(Ctrl + Fで表示される「検索」ボックスのこと)以外にも「フォルダーを指定して検索」(Ctrl + Shfit +
Fで表示される左の「検索」ビューのこと)でも同様です。ファイルが未保存状態でも、書きかけのテキストに対して検索を行う動作になっているため、開いているファイルは後述の開いていないファイルの検索と別の動作にする必要があるためだと考えられます。

## 開いていないファイルの検索の動作

開いていないファイルは「検索」ボックスでの検索対象にはなり得ませんので、「検索」ビューでワークスペース内のファイル全てを検索するときの動作についてです。こちらはより細かく追っていますので、解説していきます。

### VSCodeの中身の確認

検索を任せられることになるripgrepが実行バイナリとして同梱されています。Windowsでユーザーインストールしている場合は`%LOCALAPPDATA%\Programs\Microsoft
VS
Code\resources\app\node_modules.asar.unpacked\@vscode\ripgrep\bin\rg.exe`になります。これがそのまま実行されることになります。手元のWindows版VSCode
1.72.2 では ripgrep 13.0.0 が入っていました。

ソースコードも見てみましょう。
<https://github.com/microsoft/vscode/blob/1.72.2/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts>
にて次のようになっています。

```

    import { rgPath } from '@vscode/ripgrep';
    
```

[@vscade/ripgrep](https://www.npmjs.com/package/@vscode/ripgrep)はripgrepのMicrosoftによるプレビルドである[ripgrep-
prebuilt](https://github.com/microsoft/ripgrep-
prebuilt)の実行バイナリを内包して、実行バイナリのパス(`rgPath`)のみを提供するパッケージです。インポートされた`rgPath`はasarに含まれていないため、特有のパスに変更した`rgDiskPath`を、`RipgrepTextSearchEngine#provideTextSearchResults()`にて、[`child_process.spawn()`](https://nodejs.org/docs/latest-v16.x/api/child_process.html#child_processspawncommand-
args-options)を用いて実行されるという仕組みになっています。

実際にどのようなオプションで実行されているかは、検索が動作中に【ヘルプ】>【プロセス エクスプローラを開く】でプロセス
エクスプローラー上で確認できます。(検索がすぐに終わってまう可能性があるので、たくさんのファイルがあるディレクトリー(ルートとか)で試して見てください。)

### ripgrepが使用しているエンジン

ripgrepはRustで作られており、標準の検索エンジンは[Rustの正規表現エンジン](https://github.com/rust-
lang/regex)ですが、別途[PCRE2](https://www.pcre.org/)を使用できます(VSCode同梱の物はスタティックリンクで組み込まれている?)。Rustの正規表現エンジンには「先読み」「後読み」の機能がありませんが、PCRE2もサポートすることで「先読み」「後読み」の機能もサポートするようになっています。

PCRE2を使用するには、オプションでPCRE2を使用するように指定する方法と、オプションで自動選択にして「先読み」「後読み」がある等必要なときのみPCRE2を使用する方法があります。VSCodeでは常に自動選択`--engine
auto`オプションが設定されるため、必要な時のみ切り替わるようになっています(ripgrepのREADMEでは`-engine auto-
hybrid`と書いてあるが、問題ないようです)。(常にPCRE2を利用する`search.usePCRE2`オプションがありますが、自動選択が無かったころの対応として作られたものでであり、現在は非推奨(deprecated)となっています。[参考](https://code.visualstudio.com/updates/v1_37#_search-
regex-features))

ちょっと注意して欲しいのは、ripgrepを用いる検索といっても、使用可能な正規表現の文法はJavaScriptで使用可能な物に制限されるということです(先程の前の節の「参考」内に記載)。開いているファイルはV8の正規表現を用いるため、その動作と統一するためと思われます。

## まとめ

VSCodeの検索/置換における正規表現エンジン(「検索」ビュー「検索」ボックス問わず)

  * 開いているファイル: V8(JavaScript)
  * 開いていないファイル 
    * 先読み・後読みが無い検索: Rust
    * 先読み・後読みが有る検索: PCRE2(Perl)
CC BY-SA 4.0
2022-10-22T02:11:23.867
91733
2022-10-22T07:16:36.863
2022-10-22T07:16:36.863
7347
7347
91714
answer