1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

VSCode: 正規表現のグルーピングを使って `$1 0` に置換したい

Last updated at Posted at 2023-02-24

※ Visual Studio Code の話題です

結論を先に

数字とひっついてようが気にせず$10で置換しちゃいましょう。
いい感じに置換してくれます。

なお、ご想像の通り限界があります。(後述)

やりたいこと

以下のようなテキストファイルがあったとします。

(PowerShellでls -r > out.txtした結果の一部で、実際には数千行くらいあります)

PowerShell で ls -r > out.txt した結果の一部
    ディレクトリ: F:\Nintendo\Album


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2020/02/04      3:30                2020
d-----        2020/12/31      0:55                2019
d-----        2021/01/01     17:39                2021
d-----        2022/01/13      9:02                2022
d-----        2023/02/19     13:18                2023

時刻表示のケタが揃っていなくて扱いづらいです。
置換して00:00の表記にしましょう。

どうやるの

とりあえず簡単にこうしてみました。

^(d----- +20../../.. +) (\d:\d\d)

$10$2

…これだとグループの番号が10だと認識されそうですね。

が、気にせず置換してみちゃいます。

置換結果
    ディレクトリ: F:\Nintendo\Album


Mode                 LastWriteTime         Length Name                                                              
----                 -------------         ------ ----                                                              
d-----        2020/02/04     03:30                2020                                                              
d-----        2020/12/31     00:55                2019                                                              
d-----        2021/01/01     17:39                2021                                                              
d-----        2022/01/13     09:02                2022                                                              
d-----        2023/02/19     13:18                2023                                                              

ちゃんといい感じに00:00の表記に置換できました。

グループ10が存在しない場合、いい感じにグループ番号と文字0を分割してくれるようです。
わーぱちぱちー。

めでたしめでたし。

ちょっと待って

今回は偶然グループ10が無かったから上手に置換できたけど…
グループ10があった場合どうすれば…?

試しに、無理やりこんな感じの正規表現にしてみました。

^(d----- +20../../.. +) (\d:\d\d)(( )( )( )( )( )( )( ))

$10$2$3

(...)のグルーピングが合計で10個あります。
これはあくまでも例なので変なことをしていますが、グループが10以上になるのは十分あり得る話でしょう。
(タブ区切りのCSVで([^\t]+)\t([^\t]+)\t ... \t([^\t]+)とやったりとか…)

ひとまずさっきのファイルで置換してみます。

置換結果
    ディレクトリ: F:\Nintendo\Album


Mode                 LastWriteTime         Length Name                                                              
----                 -------------         ------ ----                                                              
 3:30                2020                                                              
 0:55                2019                                                              
d-----        2021/01/01     17:39                2021                                                              
 9:02                2022                                                              
d-----        2023/02/19     13:18                2023                                                              

予想通り、$10がグループ10だと認識され、ただの空白に置換されてしまいました。

グループ番号と数字を分割する方法は無いんでしょうか?
調べた範囲では方法はありませんでした…

なんとか置換する方法

${1}0的な感じに分割することはできないし、名前付きキャプチャもできないみたいだしなので、一時文字列を経由して置換を2回行うしか方法は無さそうです。

$1(@@@@@ファイル中に存在しない文字列#####)0
みたいな文字列にいったん変換したあと、
(@@@@@ファイル中に存在しない文字列#####)

(空文字列)
というように置換することでなんとか…

一般的なプログラミング言語では…

※ 注:知ってる限りです

PHP (PCRE)

PHP(PCRE)では、${1}0と表記することでグループと数字を分割できます。
(?P<name>pattern)とすることで名前付きキャプチャも可能ですが、置換先の指定では参照できないようです。

サクラエディタ(確認済)など、Onigumoを使う正規表現なら似たような結果になると思われます。

参考:PHP: preg_replace - Manual
参考:PHP: サブパターン - Manual
実行結果:https://wandbox.org/permlink/D4mvwFMVrvYj4WvK

Python

Pythonでは、\g<1>1と表記することでグループと数字を分割できます。
また、(?P<name>pattern)\g<name>とすることで名前付きキャプチャを用いた置換も可能です。

参考:re --- 正規表現操作 — Python 3.11.2 ドキュメント
実行結果:https://wandbox.org/permlink/N9FCFQwquJfVYf2E

JavaScript

JavaScriptでは、グループ番号と数字は分割できないようです。
その代わり、(?<name>pattern)$<name>とすることで名前付きキャプチャを用いた置換が可能です。
…VSCodeはChromiumなのでJSでの正規表現に対応してくれてても良いと思うのですが…。

参考:グループと後方参照 - JavaScript | MDN
参考:String.prototype.replace() - JavaScript | MDN
実行結果:https://wandbox.org/permlink/vO9418qsSl41GXdx

なお、古いブラウザでは未対応のようです。
ブラウザによってはそこそこ最近の実装みたい。
JavaScript built-in: RegExp: Named capture groups | Can I use... Support tables for HTML5, CSS3, etc
RegExp - JavaScript | MDN(Named capture groups の行)

参考ページ等

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?