1
2

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.

JavaScriptのmatchメソッドでマッチした文字列を取得する際のエラー回避

Last updated at Posted at 2022-04-16

前提

JSで文字列の一部をパターン指定で抽出する際、matchメソッドを用いる。
このmatchメソッドの返り値は以下の2通り。

  • マッチした場合 : Array
  • マッチしなかった場合 : null

参考:String.prototype.match() - JavaScript - MDN Web Docs

やりたいこと

マッチ結果の配列ではなく、該当した文字列を直接取得したい。
とりあえず次のようなコードを書いた。

const result = 'abc123XYZ'.match(/[0-9]{3}/)[0] // '123'

しかし、文字列の中に指定パターンが存在せずマッチしなかった場合、null[0]のような形になってしまい、エラーになる。
TypeError: Cannot read properties of null

正直な記述

matchメソッドの返り値を一度仮の変数に格納し、ifで分岐する

const temp = 'abc123XYZ'.match(/[0-9]{3}/)
let result
if (temp) {
  result = temp[0]
} 

この解決方法はあんまりイケてない。
何度も使う場合には関数にして呼び出せばまだよいかもしれないが。

また、三項演算子を使うにしても、同じmatchメソッドを2度行うような形になってしまう。

そこで今回はよりスマートな記述方法は無いかなと考えてみた。

解決方法

01: オプショナルチェーン

const resultMatched = 'abc123XYZ'.match(/[0-9]{3}/)?.[0] // '123'
const resultUnmatched = 'abcXYZ'.match(/[0-9]{3}/)?.[0] // undefined

メリットは、ワンライナーで記述できる上、可読性を考えてもまあまあ。
また、キャプチャグループを使って抽出したい場合も添え字を[1], [2]と変えれば対応できる。

02: Null合体演算子

const [resultMatched] = 'abc123XYZ'.match(/[0-9]{3}/) ?? [] // '123'
const [resultUnmatched] = 'abcXYZ'.match(/[0-9]{3}/) ?? [] // undefined

オプショナルチェーンを使うよりも若干読みづらい?同じくらいか?
キャプチャグループを使う場合は[, result]のように書く必要がある。
※読み手が左辺の宣言時点で認識できるよ、という言い分はあるかも?

最後に

ES20xxの新機能としてこれらの手法を知ってはいたものの、初めて実際にコードとして書くことができた。
その他もっと分かりやすいやり方がないかは検討します。

1
2
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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?