Wiki_JS_RegExp - inoueshinichi/Wiki_Web GitHub Wiki

JSのRegExpオブジェクト

参考

Webに特有のパターン

// JS

// emailパターン
let email = `/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:¥.[a-zA-Z0-9-]+)*$/`

// ASCII以外のパターン
let no_ascii = /[^¥u0020-¥u0070e]+/g

// 電話番号パターン
let tel = /^[0-9()+]+$/

// 郵便番号
let zipcode = /^(¥d{3}-?¥d{4}|¥d{7})$/

// URLパターン
let url = /^https?(:\/\/[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+)$/

RegExp

  • JSにおける正規表現
  • 基本: let reg = new RegExp({pattern}, {options})

オプション(options)

オプション文字列 意味
g 文字列全体に対してマッチする
i 大文字と小文字を区別する
m マルチラインモード. 複数行検索に対応する. 改行(\n)毎にマッチングを実行する
s シングルラインモード. 「.」が\nや制御文字を含む任意の文字にマッチする
u UNICODEモード. CodePoint単位でマッチングを実行する. ほぼ必須. uがない場合, CodeUnit単位検索になるので, サロゲートペアが含まれている文字列の検索を行うとnullを返す.
d マッチング範囲を記録する
y lastIndexプロパティで指定した位置らのみマッチする

gオプションの効果

  • match()メソッドは, gオプションの有無で結果が変わる
gの有無 結果 サブマッチ文字列
有効 /~/g すべてのマッチング文字列 含まれない
無効 /~/ 最初のマッチング文字列 含まれない

両方欲しい場合, str.matchAll(pattern)を用いる

  • すべてのマッチング文字列
  • サブマッチ文字列
// JS
let results = str.matchAll(re)
for (let result of results) {
  console.log(result)
}

dオプションの効果

let re_ptn = /~~~~/id

[
  'http://www.example.com/',
  undefined,
  'example',
  '/',
  // gオプション
  index: 8,
  input: ~,
  groups: undefined,
  // dオプション
  indices : [
    [8,31], undefined, [19,27], [30,31],
    groups: undefined
  ]
]
// リテラル構文
let url_p_1 = /http(s)?:\/\/([\\w-]+\\.)+(\/[\w-.\/?%&=]*)?/gi

// コンストラクタ構文
let url_p_2 = new RegExp('http(s)?://([\\w-]+\\.)+[\\w-]+(\\w-./?%&=)*)?', "gi")

全体マッチ判定

  • RegExp.test({str})
  • 戻り値は, bool
let zipcode_ptn = /[0-9]{3}(-)?[0-9]{4}/
const my_zipcode = 123-4567
if (zipcode_ptn(my_zipcode)) {
  console.log(`${my_zipcode} is match.`)
}

正規表現パターンのグループ

  • () : サブマッチ文字列にアクセスできる
// JS
let re = /(0\d{1,3})-(\d{2,4})-(\d{3,4})/
let str = "オフィスの電話番号は, 000-111-3333です."
let result str.match(re)
// 市外局番 : result[1] : 000
// 市内局番 : result[2] : 111
// 加入者番号: result[3] : 3333

名前付きキャプチャグループ

  • ()に名前をつける
  • ?<名前>でのちにresult.groups.名前でアクセスできる
let re = /(?<area>0\d{1,3})-(?<city>\d{2,4})-(?<local>\d{3,4})/
let str = "オフィスの電話番号は, 000-111-3333です."
let result str.match(re)
// 市外局番 : result.groups.area 000
// 市内局番 : result.groups.city 111
// 加入者番号 : result.groups.local 3333

マッチする部分文字列の探索

String.search

  • 基本: RegExp.search({str})
  • 戻り値 : ahead index > 0 if MATCH else -1

String.match

  • 基本 : String.({pattern})
  • 戻り値 : マッチした部分文字列

gオプションを外した場合のString.matchの挙動

| 0 |・・・最初に一致した文字列全体
| 1 |・・・サブマッチ文字列[1] : ()に対する複数回マッチしたら最後のみ
| 2 |・・・サブマッチ文字列[2]
| 3 |
| : |
| N |
  • 拡張プロパティ
  • index: マッチした文字列の位置
  • input: 検索対象文字列 
  • groups: 名前付きキャプチャグループにマッチした文字列

String.replaceメソッド

  • str.replace(pattern, rep)
  • $&: マッチした部分文字列
  • `$``: マッチした部分文字列の直前の文字列
  • $': マッチした部分文字列の直後の文字列
  • $1~100: サブマッチ文字列の長さ
  • $$: ドル記号

String.replaceAllメソッド

  • str.replaceAll(pattern, rep)
  • gオプションがないとエラーになる
// e.g. URL文字列をanchorタグ<a>に置換する
// JS
let re = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/gi
let str = "サポートサイトは, http://www.example.com/です。"
str.replaceAll(re, '<a href="$&">$&</a>')

String.splitメソッド

  • 正規表現で文字列を分割する
let re = /[\/\.\-]/g
"2022/12/04".split(re) // ["2022", "12", "04"]
"2022-12-04".split(re) // ["2022", "12", "04"]
"2022.12.04".split(re) // ["2022", "12", "04"]

最長一致と最短一致

  • <.+>: 最長一致
  • <+?>: 最短一致
  • <*?>, {1,3}?, <??>
⚠️ **GitHub.com Fallback** ⚠️