0
Help us understand the problem. What are the problem?

posted at

updated at

メモ: Perl、split 関数で 'abc123def456ghi' を英数字境界で区切る正規表現

2021年11月27日 15時19分

Perl、split 関数で 'abc123def456ghi' を英数字境界で区切るパターンを考えてみた。

境界、文字と文字の間

split はマッチした部分の文字列を、区切り後の文字列には含めないから、英数字そのものをマッチしちゃダメ。「文字と文字の間」つまり文字の「境界」にマッチしなきゃならない。境界といえば \b があるけど、これは使えない。

というゆわけで使えるのは後読みパターン (?<=)先読みパターン (?=)。こいつらが使えるのはこいつらはマッチング後にカーソル位置を進めないから、マッチする文字列の長さがゼロになる。だから事実上、境界にマッチしたことと同じになる。

今回は数字列とそれ以外の文字との境界を検出する方法で考えてみた。

数字列の最初の位置にマッチするパターン (?<=[^0-9])(?=[0-9])
数字列の最初の位置にマッチするパターン (?<=[0-9])(?=[^0-9])

このパターンは数字列が文字列の先頭や文字列の末尾にある場合にはマッチしない

use feature 'say' ;

$_ = 'abc123def456ghi' ;

@_ = split /(?<=[^0-9])(?=[0-9])/ ;# 数字列の先頭にマッチ
say '1:', map {"[$_]"} @_ ;

@_ = split /(?<=[0-9])(?=[^0-9])/ ;# 数字列の末尾にマッチ
say '2:', map {"[$_]"} @_ ;

この出力はこうなる。

1:[abc][123def][456ghi]
2:[abc123][def456][ghi]

でこれら二つのパターンを | で合体すれば完成。

@_ = split /(?<=[^0-9])(?=[0-9])|(?<=[0-9])(?=[^0-9])/ ;
say '3:', map {"[$_]"} @_ ;

この出力はこうなる。

3:[abc][123][def][456][ghi]
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
0
Help us understand the problem. What are the problem?