職案人

求職・歴史・仏教などについて掲載するつもりだが、自分の思いつきが多いブログだよ。適当に付き合って下さい。

JS--マッチした文字列の置換

2024年04月20日 | JavaScript

マッチした文字列の置換

【開発環境】
OS:Win11(64ビット)
VSCode1.72.2、
クロム

【置換の対象を正規表現を使って指定する】
String オブジェクトの replace メソッドは、対象の文字列の中の指定した文字列を、別の文字列で置換した新しい文字列を返します。

・書式

文字列.replace(置換する文字列, 新しい文字列)

引数の置換する文字列には固定の文字列を指定することもできますが、正規表現オブジェクトを指定することもできます。

文字列.replace(正規表現, 新しい文字列)

対象の文字列の中で 1 番目で指定した正規表現にマッチした文字列2 番目で指定した文字列に置換します。対象の文字列に変更は行わず、置換したあとの新しい文字列が返されます。

・正規表現にグローバルフラグが設定されていない場合
対象の文字列の中の最初に正規表現にマッチした文字列だけが置換される。

・正規表現にグローバルフラグが設定されていた場合
マッチしたすべての文字列が置換される。

サンプル

let str = 'Border Color is Red, Line Color is RED';
let newstr = str.replace(/(Red|RED)/, 'red');

console.log(newstr);実行
> Border Color is red, Line Color is RED

対象の文字列の中に Red または RED が含まれていた場合は red に置換します。 今回のサンプルのように正規表現オブジェクトにグローバルフラグ設定されていない場合は最初にマッチした文字列だけを置換する。

グローバルフラグが設定されている場合のサンプル

let str = 'Border Color is Red, Line Color is RED';
let newstr = str.replace(/(Red|RED)/g, 'red');

console.log(newstr);
> Border Color is red, Line Color is red

グローバルフラグが設定されているため、対象の文字列の中で正規表現にマッチするすべての文字列が置換されました。

【キャプチャグループにマッチした文字列を参照する】

replace メソッドでは置換する新しい文字列としてドル記号($)を使った特別な値を記述することができます。

$&  マッチした部分文字列
$`  マッチした部分の前の文字列
$'  マッチした部分の後の文字列
$$  $の文字

上記に加えて、置換する対象の文字列として正規表現を指定した場合に、正規表現の中でキャプチャグループが含まれている場合は $1, $2, ... を使用することでキャプチャグループでキャプチャされた文字列を参照することができます。

$1, $2, ...  キャプチャグループでキャプチャされた文字列

サンプル

let str = '誕生日は 1994-04-21 です';
let regexp = /(\d{4})-(\d{2})-(\d{2})/;
let newstr = str.replace(regexp, '$1年$2月$3日');

console.log(newstr);
>> 誕生日は 1994年04月21日 です

【置換する新しい文字列として関数を指定する】

replace メソッドの 2 番目の引数には置換する新しい文字列を指定しますが、文字列の代わりにコールバック関数を指定することもできます。
関数を指定した場合は、 1 番目の引数に指定した文字列または正規表現がマッチした時点で関数が呼び出され、関数からの戻り値が新しい値として置換を行います。

文字列.replace(正規表現, 関数) 

関数は呼び出される時に最大で次の引数を受け取ります。必要な数の引数を受け取り、関数のブロック内で置換する文字列を return 文を使って返してください。

match     パターンにマッチした文字列
c1,c2,... パターンにキャプチャグループが含まれる場合にキャプチャした文字列
offset    マッチした文字列の先頭文字のインデックス
str       対象の文字列

サンプル

let str = 'Border Color is GREEN, Line Color is RED';//小文字に変換する
let newstr = str.replace(/[A-Z].+?\b/g, function(match){
  return match.toLowerCase();
});

console.log(newstr);
>> border color is green, line color is red

今回のサンプルでは大文字から始まる単語にマッチする正規表現パターンを指定して置換を行います。
置換する新しい文字列は、コールバック関数内でマッチした文字列をすべて小文字に変換した文字列を return 文で返しています。
グローバルフラグを設定しているので、対象の文字列の中で正規表現にマッチするすべての文字列が置換されます。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

JS--文字列を正規表現を使って区切るには

2024年04月18日 | 哲学

文字列を正規表現を使って区切るには

【開発環境】
OS:Win11(64ビット)
VSCode1.72.2、
クロム

【区切り文字として正規表現を指定する】
split メソッドは、対象の文字列を指定した区切り文字で分割し、分割された文字列をそれぞれ要素として格納した配列を返します。
・書式

文字列.split([区切り文字[, 最大分割回数]])

引数の区切り文字には文字列を指定することもできますが、正規表現オブジェクトを指定することもできます。

文字列.split([正規表現[, 最大分割回数]])

サンプル
let msg = `こんにちは。今日は、朝から快晴
で気持ちがいいですね。散歩が楽しいです。`;
let msgAry = msg.split(/[。、\n]/);

console.log(msgAry);
>> ["こんにちは", "今日は", "朝から快晴", "で気持ちがいいですね", "散歩が楽しいです", ""]

対象の文字列はテンプレートリテラルを使って改行を含めて入力されています。
split メソッドの引数に指定する正規表現のパターンには「。」「、」「\n(改行)」のいずれかにマッチするものを指定しました。


split メソッドを実行すると正規表現で指定した 3 つの文字のいずれかの文字で対象の文字列を分割します。

このように区切り文字として正規表現オブジェクトを指定することで、より柔軟に対象の文字列を分割することができます。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

JS--マッチした文字列の取得

2024年04月17日 | JavaScript

マッチした文字列を取得するには

【開発環境】
OS:Win11(64ビット)
VSCode1.72.2、
クロム

【matchメソッドの使い方】
String オブジェクトの match メソッドは、対象となる文字列が正規表現とマッチした場合に、マッチした文字列を取得します。書式は次の通りです。

文字列.match(正規表現オブジェクト)

文字列が引数に指定した正規表現とマッチした場合
マッチした文字列が格納された配列を返します。

マッチしなかった場合
null を返します。

戻り値の配列には
インデックス 0 の要素にパターン全体にマッチした文字列が、
インデックス 1 以降の要素には設定したキャプチャグループで囲んだパターンにマッチした文字列が格納される。
(キャプチャグループを設定していない場合はインデックス 1 以降の要素は存在しません)。

サンプル

let regexp = /20\d{2}-\d{2}-\d{2}/;
let str1 = 'Today is 2020-08-14';
let str2 = 'Yesterday is 1998-12-07';

let result1 = str1.match(regexp);
console.log(result1[0]);実行> 2020-08-14

let result2 = str2.match(regexp);
console.log(result2[0]);実行
> TypeError: Cannot read property '0' of null

【try~catch】
・文字列が正規表現にマッチした場合
パターン全体がマッチした文字列がインデックス 0 の要素の値として格納された配列として受取る

・マッチしなかった場合
戻り値は null となり、 null に対してインデックス 0 の要素を取得しようとすると TypeError が発生する。

サンプル

let regexp = /20\d{2}-\d{2}-\d{2}/;
let str = 'Yesterday is 1998-12-07';

let result = str.match(regexp);
try{
  console.log(result[0]);
} catch(e) {
  console.log('Not Match');
}

>> Not Match

【パターンにキャプチャグループが含まれる場合】
パターンにキャプチャグループが含まれている場合
キャプチャグループを作成するには、パターンの中を括弧()で囲います。するとキャプチャグループに設定したパターンの部分にマッチした文字列を取得することが出来る。
・サンプル

let regexp = /(20\d{2})-(\d{2})-(\d{2})/;
let str = 'Today is 2020-08-14';

let result = str.match(regexp);
for (let i = 0 ; i >> i=0, match=2020-08-14
>> i=1, match=2020
>> i=2, match=08
>> i=3, match=14
 

正規表現にマッチした場合→戻り値として配列を受け取る。
インデックス 0 の要素→パターン全体がマッチした文字列が格納される。
インデックス 1 以降の要素→それぞれキャプチャグループで囲まれたパターンにマッチした文字列が格納されている。

【パターンに名前付きキャプチャグループが含まれる場合】

JavaScript では名前付きキャプチャグループも利用することができます。書式は次の通りです。

(?<グループ名>パターン)

名前のないキャプチャグループの場合、 match メソッドの戻り値である配列に含まれるインデックス 1 以降の要素の値を参照することでキャプチャした文字列を取得することができましたが、名前付きキャプチャグループでキャプチャした文字列は次の書式で参照することができます。

配列.groups.グループ名

サンプル
let regexp = /(?20\d{2})-(?\d{2})-(?\d{2})/;
let str = 'Today is 2020-08-14';

let result = str.match(regexp);
let year = result.groups.year;
let month = result.groups.month;
let day = result.groups.day;

console.log(year + '年' + month + '月' + day + '日');
実行
>2020年08月14

名前付きキャプチャグループのキャプチャ(保存する)をそれぞれ取得し、 1 つの文字列にまとめて出力しました。

できることは名前付きであっても名前がなくても同じですがキャプチャグループの番号で指定するよりもグループ名で指定してキャプチャを取得下方が分かりやすいコードにはなるかと思います。

【マッチした文字列の位置を参照する】
match メソッドを実行して文字列が正規表現にマッチした場合、マッチした文字列の先頭文字のインデックスが戻り値として取得した配列の index プロパティに設定されます。そこで index プロパティを参照することでマッチした文字列の位置を参照することができます。インデックスは対象の文字列の先頭文字が 0 、次の文字が 1 、と続いていきます。

サンプル

let regexp = /20\d{2}-\d{2}-\d{2}/;
let str = 'Today is 2020-08-14';

let result = str.match(regexp);
console.log(result[0]);
> 2020-08-14
console.log(result.index);
> 9

【グローバルフラグが設定されている場合】

パターンの最後に g を記述するとグローバルフラグを設定することができます。

/パターン/g

・正規表現にグローバルフラグが設定されている場合
match メソッドを実行すると対象の文字列の中で正規表現がマッチするすべての文字列が格納された配列を返します。

・グローバルフラグが設定されている場合
パターンにキャプチャグループが設定されていてもキャプチャは取得することができません。

サンプル

let regexp = /[A-Z].+?day/g;
let str = 'Sunday Monday Tuesday';

let result = str.match(regexp);
for (let i = 0 ; i > Sunday
> Monday
> Tuesday対象の文字列の中でパターンに一致するすべての文字列を取得することができました。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

JS--マッチした文字列のインデックス取得

2024年04月15日 | JavaScript
文字列のインデックス取得

【開発環境】
OS:Win11(64ビット)
VSCode1.72.2、
クロム

【searchメソッドの使い方】

String オブジェクトの search メソッドは、対象となる文字列が正規表現とマッチした場合に、マッチした最初の文字列のインデックスを返します。書式は次の通りです。

文字列.search(正規表現オブジェクト)

・マッチした場合
最初にマッチした文字列の先頭文字のインデックスを返します。
・マッチしなかった場合
「-1 」を返します。

インデックスは対象の文字列の先頭文字が 0 、次の文字が 1 、と続いていきます。

サンプル

let regexp = /ball/;
let str1 = 'baseball and football';
let str2 = 'Make a cake tomorrow';

console.log(str1.search(regexp));実行> 4
console.log(str2.search(regexp));実行
> -1

対象の文字列では正規表現にマッチする箇所が 2 つありますが、最初にマッチした文字列の先頭文字のインデックスである 4 が返されます。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

JS--正規表現にマッチした文字列を取得する

2024年04月11日 | JavaScript

正規表示にマッチした文字列を取得する

【開発環境】
OS:Win11(64ビット)
VSCode1.72.2、
クロム

【execメソッドの使い方】
RegExp オブジェクトの exec メソッドは、対象となる文字列が正規表現とマッチした場合に、マッチした文字列を取得します
書式は次の通りです。

正規表現オブジェクト.exec(文字列)

引数に指定した文字列が正規表現とマッチした場合は、マッチした文字列が格納された配列を返します。マッチしなかった場合は null を返します。
戻り値の配列には
インデックス 0 の要素にパターン全体にマッチした文字列、
インデックス 1 以降の要素には設定したキャプチャグループで囲んだパターンにマッチした文字列が格納されます。
(キャプチャグループを設定していない場合はインデックス 1 以降の要素は存在しません)。

配列[0]  パターン全体にマッチした文字列
配列[1]  キャプチャグループ1にマッチした文字列
配列[2]  キャプチャグループ2にマッチした文字列
・・・
配列[n]  キャプチャグループnにマッチした文字列

サンプル

let regexp = /20\d{2}-\d{2}-\d{2}/;

let result1 = regexp.exec('Today is 2020-08-14');
console.log(result1[0]);実行
> 2020-08-14

let result2 = regexp.exec('Yesterday is 1998-12-07');
console.log(result2[0]);実行
> TypeError: Cannot read property '0' of null

文字列が正規表現にマッチした場合には、パターン全体がマッチした文字列がインデックス 0 の要素の値として格納された配列として受け取ります。

ただマッチしなかった場合には戻り値は null となり、 null に対してインデックス 0 の要素を取得しようとすると TypeError が発生します。

次のように null かどうかの条件分岐を追加するか例外処理を行ってください。

let regexp = /20\d{2}-\d{2}-\d{2}/;

let result = regexp.exec('Yesterday is 1998-12-07');
if (result !== null){
  console.log(result[0]);
}else{
  console.log('Not Match');
}
実行
> Not Match

【パターンにキャプチャグループが含まれる場合】
続いてパターンにキャプチャグループが含まれている場合です。
キャプチャグループを作成するには、パターンの中を括弧()で囲います。
するとキャプチャグループに設定したパターンの部分にマッチした文字列を取得することができます。

サンプル

let regexp = /(20\d{2})-(\d{2})-(\d{2})/;

let result = regexp.exec('Today is 2020-08-14');
for (let i = 0 ; i > i=0, match=2020-08-14
> i=1, match=2020
> i=2, match=08
> i=3, match=14

文字列が正規表現にマッチした場合は、戻り値として配列を受け取ります。インデックス 0 の要素にはパターン全体がマッチした文字列が格納される。
インデックス 1 以降の要素にはそれぞれキャプチャグループで囲まれたパターンにマッチした文字列が格納される。

【マッチした文字列の位置を参照する】
exec メソッドを実行して文字列が正規表現にマッチした場合、
マッチした文字列の先頭文字のインデックス戻り値として取得した配列の index プロパティに設定される。
そのため、 index プロパティを参照することでマッチした文字列の位置を参照することができます。
インデックスは対象の文字列の先頭文字が 0 、次の文字が 1 、と続いていきます。

サンプルコード

let regexp = /20\d{2}-\d{2}-\d{2}/;

let result = regexp.exec('Today is 2020-08-14');
console.log(result[0]);実行
> 2020-08-14
console.log(' lastIndex=' + result.index);実行
> lastIndex=9


対象の文字列の中で、正規表現にマッチした文字列の先頭文字のインデックスを参照することができました。

【グローバルフラグを設定してる場合】

パターンの最後に g を記述するとグローバルフラグを設定することができます。

/パターン/g

正規表現にグローバルフラグが設定されている場合
→exec メソッドを実行し文字列が正規表現にマッチすると、正規表現オブジェクトの lastIndex プロパティの値がマッチした文字列の次の文字のインデックスに設定されます。
(グローバルフラグが設定されていない場合は、 exec メソッドでマッチしたとしても lastIndex は 0 のままです)。

サンプル

let regexp = /[A-Z].+?day/g;
let str = 'Sunday Monday Tuesday';

let result = regexp.exec(str);
console.log(result[0]);実行> Sunday
console.log(' lastIndex=' + regexp.lastIndex);実行
> lastIndex=6

そのあとで同じ正規表現に対して同じ文字列を引数に指定して exec メソッドを実行すると、現在の lastIndex が示す文字列の位置から正規表現とマッチする文字列を取得します。再びマッチした場合は、改めて lastIndex プロパティの値が更新されます。

サンプル

let regexp = /[A-Z].+?day/g;
let str = 'Sunday Monday Tuesday';

let result = regexp.exec(str);
console.log(result[0]);実行
> Sunday
console.log(' lastIndex=' + regexp.lastIndex);実行
> lastIndex=6

result = regexp.exec(str);
console.log(result[0]);実行
> Monday
console.log(' lastIndex=' + regexp.lastIndex);実行
> lastIndex=13

exec メソッドを実行したときに正規表現にマッチしなかった場合には lastIndex は 0 に戻ります。

let regexp = /[A-Z].+?(day)/g;
let str = 'Sunday Monday Tuesday';

let result = regexp.exec(str);
while (result !== null){
  console.log(result[0]);
  console.log(result[1]);
  console.log(' lastIndex=' + regexp.lastIndex);

  result = regexp.exec(str);
}
console.log(' lastIndex=' + regexp.lastIndex);

>> Sunday
>> day
>> lastIndex=6
>> Monday
>> day
>> lastIndex=13
>> Tuesday
>> day
>> lastIndex=21
>> lastIndex=0

このようにグローバルフラグを設定することで、同じ文字列に対して正規表現が複数回マッチするかどうか確認しマッチした場合はその文字列を取得することができます。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする