@digitalwalletcorp/utils 0.2.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -13
- package/lib/crypto-util-DFJqfmuw.js +46 -0
- package/lib/crypto-util-DFJqfmuw.js.map +1 -0
- package/lib/crypto-util-DeZSGetI.cjs +2 -0
- package/lib/crypto-util-DeZSGetI.cjs.map +1 -0
- package/lib/crypto-util.cjs +2 -0
- package/lib/crypto-util.cjs.map +1 -0
- package/lib/crypto-util.d.cts +28 -0
- package/lib/crypto-util.d.ts +28 -0
- package/lib/crypto-util.js +7 -0
- package/lib/crypto-util.js.map +1 -0
- package/lib/date-util-CG7L8nSP.js +184 -0
- package/lib/date-util-CG7L8nSP.js.map +1 -0
- package/lib/date-util-DopNKy3u.cjs +2 -0
- package/lib/date-util-DopNKy3u.cjs.map +1 -0
- package/lib/date-util.cjs +2 -0
- package/lib/date-util.cjs.map +1 -0
- package/lib/date-util.d.cts +231 -0
- package/lib/date-util.d.ts +231 -0
- package/lib/date-util.js +23 -0
- package/lib/date-util.js.map +1 -0
- package/lib/decimal.cjs +2 -0
- package/lib/decimal.cjs.map +1 -0
- package/lib/decimal.d.cts +197 -0
- package/lib/decimal.d.ts +197 -0
- package/lib/decimal.js +227 -0
- package/lib/decimal.js.map +1 -0
- package/lib/file-util-D09BvDYY.cjs +2 -0
- package/lib/file-util-D09BvDYY.cjs.map +1 -0
- package/lib/file-util-H-c_eQcd.js +140 -0
- package/lib/file-util-H-c_eQcd.js.map +1 -0
- package/lib/file-util.cjs +2 -0
- package/lib/file-util.cjs.map +1 -0
- package/lib/file-util.d.cts +119 -0
- package/lib/file-util.d.ts +119 -0
- package/lib/file-util.js +18 -0
- package/lib/file-util.js.map +1 -0
- package/lib/html-util-CcRJtzod.js +56 -0
- package/lib/html-util-CcRJtzod.js.map +1 -0
- package/lib/html-util-ClGIpzW1.cjs +2 -0
- package/lib/html-util-ClGIpzW1.cjs.map +1 -0
- package/lib/html-util.cjs +2 -0
- package/lib/html-util.cjs.map +1 -0
- package/lib/html-util.d.cts +84 -0
- package/lib/html-util.d.ts +84 -0
- package/lib/html-util.js +10 -0
- package/lib/html-util.js.map +1 -0
- package/lib/index.cjs +1 -1
- package/lib/index.d.cts +8 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +18 -2
- package/lib/index.js.map +1 -1
- package/lib/json-util-5mq7fsX_.cjs +4 -0
- package/lib/json-util-5mq7fsX_.cjs.map +1 -0
- package/lib/json-util-CF-O1b7m.js +149 -0
- package/lib/json-util-CF-O1b7m.js.map +1 -0
- package/lib/json-util.cjs +2 -0
- package/lib/json-util.cjs.map +1 -0
- package/lib/json-util.d.cts +58 -0
- package/lib/json-util.d.ts +58 -0
- package/lib/json-util.js +8 -0
- package/lib/json-util.js.map +1 -0
- package/lib/number-util-BA4KVFyF.js +198 -0
- package/lib/number-util-BA4KVFyF.js.map +1 -0
- package/lib/number-util-BaSf1wWH.cjs +2 -0
- package/lib/number-util-BaSf1wWH.cjs.map +1 -0
- package/lib/number-util.cjs +1 -1
- package/lib/number-util.d.cts +65 -51
- package/lib/number-util.d.ts +65 -51
- package/lib/number-util.js +19 -14
- package/lib/object-util-6uts5Xax.cjs +2 -0
- package/lib/object-util-6uts5Xax.cjs.map +1 -0
- package/lib/object-util-auzl09b5.js +204 -0
- package/lib/object-util-auzl09b5.js.map +1 -0
- package/lib/object-util.cjs +2 -0
- package/lib/object-util.cjs.map +1 -0
- package/lib/object-util.d.cts +157 -0
- package/lib/object-util.d.ts +157 -0
- package/lib/object-util.js +16 -0
- package/lib/object-util.js.map +1 -0
- package/lib/string-util-Cw0VgbIH.js +52 -0
- package/lib/string-util-Cw0VgbIH.js.map +1 -0
- package/lib/string-util-w2I5EYuY.cjs +2 -0
- package/lib/string-util-w2I5EYuY.cjs.map +1 -0
- package/lib/string-util.cjs +2 -0
- package/lib/string-util.cjs.map +1 -0
- package/lib/string-util.d.cts +51 -0
- package/lib/string-util.d.ts +51 -0
- package/lib/string-util.js +8 -0
- package/lib/string-util.js.map +1 -0
- package/package.json +26 -8
- package/src/crypto-util.ts +84 -0
- package/src/date-util.ts +448 -0
- package/src/decimal.ts +294 -0
- package/src/file-util.ts +281 -0
- package/src/html-util.ts +215 -0
- package/src/index.ts +8 -0
- package/src/json-util.ts +291 -0
- package/src/number-util.ts +141 -194
- package/src/object-util.ts +482 -0
- package/src/string-util.ts +115 -0
- package/lib/number-util-DHq-ux31.js +0 -253
- package/lib/number-util-DHq-ux31.js.map +0 -1
- package/lib/number-util-DiMi-j7B.cjs +0 -2
- package/lib/number-util-DiMi-j7B.cjs.map +0 -1
- package/lib/reg-exp-matcher.cjs +0 -2
- package/lib/reg-exp-matcher.cjs.map +0 -1
- package/lib/reg-exp-matcher.d.cts +0 -85
- package/lib/reg-exp-matcher.d.ts +0 -85
- package/lib/reg-exp-matcher.js +0 -94
- package/lib/reg-exp-matcher.js.map +0 -1
- package/src/reg-exp-matcher.ts +0 -154
package/lib/reg-exp-matcher.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
class h {
|
|
2
|
-
regexp;
|
|
3
|
-
matcher = null;
|
|
4
|
-
str = "";
|
|
5
|
-
appendPosition = 0;
|
|
6
|
-
exhausted = !1;
|
|
7
|
-
buffer = [];
|
|
8
|
-
/**
|
|
9
|
-
* @param {string | RegExp} pattern 文字列の場合はglobal属性を付与して解釈する。RegExpの場合はglobal属性の有無を問わない
|
|
10
|
-
*/
|
|
11
|
-
constructor(t) {
|
|
12
|
-
this.regexp = typeof t == "string" ? new RegExp(t, "g") : new RegExp(t.source, t.flags.includes("g") ? t.flags : `${t.flags}g`);
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* 走査対象の文字列を設定し、走査位置とバッファを先頭に戻す
|
|
16
|
-
*
|
|
17
|
-
* @param {string} str
|
|
18
|
-
*/
|
|
19
|
-
reset(t) {
|
|
20
|
-
this.str = t, this.matcher = null, this.appendPosition = 0, this.exhausted = !1, this.buffer = [], this.regexp.lastIndex = 0;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* 次のマッチ箇所へ進める
|
|
24
|
-
* これ以上マッチしなくなった後は、reset()するまでfalseを返し続ける
|
|
25
|
-
*
|
|
26
|
-
* @returns {boolean} マッチした場合はtrue
|
|
27
|
-
*/
|
|
28
|
-
find() {
|
|
29
|
-
if (this.exhausted)
|
|
30
|
-
return !1;
|
|
31
|
-
if (this.matcher = this.regexp.exec(this.str), !this.matcher)
|
|
32
|
-
return this.exhausted = !0, !1;
|
|
33
|
-
if (this.matcher[0] === "") {
|
|
34
|
-
const t = /[uv]/.test(this.regexp.flags), e = this.str.codePointAt(this.regexp.lastIndex);
|
|
35
|
-
this.regexp.lastIndex += t && e !== void 0 && e > 65535 ? 2 : 1;
|
|
36
|
-
}
|
|
37
|
-
return !0;
|
|
38
|
-
}
|
|
39
|
-
group(t = 0) {
|
|
40
|
-
const e = this.currentMatcher();
|
|
41
|
-
if (t < 0 || e.length <= t)
|
|
42
|
-
throw new RangeError(`No group ${t}`);
|
|
43
|
-
return e[t] ?? null;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* 現在のマッチ情報を返す
|
|
47
|
-
*
|
|
48
|
-
* @returns {RegExpExecArray | null} マッチしていない場合はnull
|
|
49
|
-
*/
|
|
50
|
-
getMatcher() {
|
|
51
|
-
return this.matcher;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* 前回の置換位置から現在のマッチ箇所までの不一致文字列と、マッチ箇所の置換文字列をバッファに追加する
|
|
55
|
-
*
|
|
56
|
-
* @param {Replacement} replace 置換文字列、または置換関数。置換文字列の `$1` などは解釈せずそのまま出力するため、グループを参照する場合は置換関数を渡す
|
|
57
|
-
* @param {(notMatch: string) => string} [notMatchReplacer] 不一致文字列の置換関数
|
|
58
|
-
* @throws {Error} マッチしていない場合
|
|
59
|
-
* @throws {RangeError} 現在のマッチに対して既に呼び出している場合
|
|
60
|
-
*/
|
|
61
|
-
appendReplacement(t, e) {
|
|
62
|
-
const s = this.currentMatcher();
|
|
63
|
-
if (s.index < this.appendPosition)
|
|
64
|
-
throw new RangeError("appendReplacement has already been called for the current match");
|
|
65
|
-
const r = this.str.slice(this.appendPosition, s.index);
|
|
66
|
-
this.buffer.push(e ? e(r) : r), this.buffer.push(typeof t == "function" ? t(s) : t), this.appendPosition = s.index + s[0].length;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* 前回の置換位置から末尾までの文字列をバッファに追加する
|
|
70
|
-
*
|
|
71
|
-
* @param {(tail: string) => string} [tailReplacer] 末尾文字列の置換関数
|
|
72
|
-
*/
|
|
73
|
-
appendTail(t) {
|
|
74
|
-
const e = this.str.slice(this.appendPosition);
|
|
75
|
-
this.buffer.push(t ? t(e) : e);
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* バッファに追加した文字列を連結して返す
|
|
79
|
-
*
|
|
80
|
-
* @returns {string}
|
|
81
|
-
*/
|
|
82
|
-
toString() {
|
|
83
|
-
return this.buffer.join("");
|
|
84
|
-
}
|
|
85
|
-
currentMatcher() {
|
|
86
|
-
if (!this.matcher)
|
|
87
|
-
throw new Error("No match available");
|
|
88
|
-
return this.matcher;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
export {
|
|
92
|
-
h as RegExpMatcher
|
|
93
|
-
};
|
|
94
|
-
//# sourceMappingURL=reg-exp-matcher.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reg-exp-matcher.js","sources":["../src/reg-exp-matcher.ts"],"sourcesContent":["/**\n * 置換文字列、または現在のマッチ情報から置換文字列を返す関数\n */\nexport type Replacement = string | ((matcher: RegExpExecArray) => string);\n\n/**\n * マッチ箇所ごとに置換内容を決めながら文字列を組み立てる。\n *\n * 例)\n * const regExpMatcher = new RegExpMatcher(/\\:([^/?]+)/g);\n * regExpMatcher.reset('/EWM/WalletID/:WalletID/Job/:JobID');\n * while (regExpMatcher.find()) {\n * const match = regExpMatcher.group();\n * if (match === ':WalletID') {\n * regExpMatcher.appendReplacement('12345');\n * }\n * if (match === ':JobID') {\n * regExpMatcher.appendReplacement('99999999');\n * }\n * }\n * regExpMatcher.appendTail();\n * regExpMatcher.toString(); // '/EWM/WalletID/12345/Job/99999999'\n */\nexport class RegExpMatcher {\n\n private readonly regexp: RegExp;\n private matcher: RegExpExecArray | null = null;\n private str = '';\n private appendPosition = 0;\n private exhausted = false;\n private buffer: string[] = [];\n\n /**\n * @param {string | RegExp} pattern 文字列の場合はglobal属性を付与して解釈する。RegExpの場合はglobal属性の有無を問わない\n */\n constructor(pattern: string | RegExp) {\n // 走査にはglobal属性が必要。呼び出し側のRegExpのlastIndexを汚さないよう、渡されたRegExpは使わず複製する\n this.regexp = typeof pattern === 'string'\n ? new RegExp(pattern, 'g')\n : new RegExp(pattern.source, pattern.flags.includes('g') ? pattern.flags : `${pattern.flags}g`);\n }\n\n /**\n * 走査対象の文字列を設定し、走査位置とバッファを先頭に戻す\n *\n * @param {string} str\n */\n public reset(str: string): void {\n this.str = str;\n this.matcher = null;\n this.appendPosition = 0;\n this.exhausted = false;\n this.buffer = [];\n this.regexp.lastIndex = 0;\n }\n\n /**\n * 次のマッチ箇所へ進める\n * これ以上マッチしなくなった後は、reset()するまでfalseを返し続ける\n *\n * @returns {boolean} マッチした場合はtrue\n */\n public find(): boolean {\n if (this.exhausted) {\n return false;\n }\n this.matcher = this.regexp.exec(this.str);\n if (!this.matcher) {\n // execは失敗するとlastIndexを0に戻し、次の呼び出しで先頭から再びマッチしてしまうため、走査済みとして止める\n this.exhausted = true;\n return false;\n }\n if (this.matcher[0] === '') {\n // 空文字にマッチするとlastIndexが進まず同じ位置を繰り返すため、1文字(u/v属性ありならコードポイント1つ)進める\n // v属性ではunicodeがfalseになるためflagsで判定する。サロゲートペアの途中から走査すると先頭に戻ってしまい無限ループになる\n const isUnicode = /[uv]/.test(this.regexp.flags);\n const codePoint = this.str.codePointAt(this.regexp.lastIndex);\n this.regexp.lastIndex += isUnicode && codePoint !== undefined && codePoint > 0xffff ? 2 : 1;\n }\n return true;\n }\n\n /**\n * 現在のマッチ文字列を返す\n *\n * @param {number} [index] キャプチャグループの番号。省略時はマッチ全体\n * @returns {string | null} グループがマッチに参加しなかった場合はnull\n * @throws {Error} マッチしていない場合\n * @throws {RangeError} 存在しないグループ番号を指定した場合\n */\n public group(): string;\n public group(index: number): string | null;\n public group(index = 0): string | null {\n const matcher = this.currentMatcher();\n if (index < 0 || matcher.length <= index) {\n throw new RangeError(`No group ${index}`);\n }\n return matcher[index] ?? null;\n }\n\n /**\n * 現在のマッチ情報を返す\n *\n * @returns {RegExpExecArray | null} マッチしていない場合はnull\n */\n public getMatcher(): RegExpExecArray | null {\n return this.matcher;\n }\n\n /**\n * 前回の置換位置から現在のマッチ箇所までの不一致文字列と、マッチ箇所の置換文字列をバッファに追加する\n *\n * @param {Replacement} replace 置換文字列、または置換関数。置換文字列の `$1` などは解釈せずそのまま出力するため、グループを参照する場合は置換関数を渡す\n * @param {(notMatch: string) => string} [notMatchReplacer] 不一致文字列の置換関数\n * @throws {Error} マッチしていない場合\n * @throws {RangeError} 現在のマッチに対して既に呼び出している場合\n */\n public appendReplacement(replace: Replacement, notMatchReplacer?: (notMatch: string) => string): void {\n const matcher = this.currentMatcher();\n if (matcher.index < this.appendPosition) {\n throw new RangeError('appendReplacement has already been called for the current match');\n }\n const notMatch = this.str.slice(this.appendPosition, matcher.index);\n this.buffer.push(notMatchReplacer ? notMatchReplacer(notMatch) : notMatch);\n this.buffer.push(typeof replace === 'function' ? replace(matcher) : replace);\n this.appendPosition = matcher.index + matcher[0].length;\n }\n\n /**\n * 前回の置換位置から末尾までの文字列をバッファに追加する\n *\n * @param {(tail: string) => string} [tailReplacer] 末尾文字列の置換関数\n */\n public appendTail(tailReplacer?: (tail: string) => string): void {\n const tail = this.str.slice(this.appendPosition);\n this.buffer.push(tailReplacer ? tailReplacer(tail) : tail);\n }\n\n /**\n * バッファに追加した文字列を連結して返す\n *\n * @returns {string}\n */\n public toString(): string {\n return this.buffer.join('');\n }\n\n private currentMatcher(): RegExpExecArray {\n if (!this.matcher) {\n throw new Error('No match available');\n }\n return this.matcher;\n }\n}\n"],"names":["RegExpMatcher","pattern","str","isUnicode","codePoint","index","matcher","replace","notMatchReplacer","notMatch","tailReplacer","tail"],"mappings":"AAuBO,MAAMA,EAAc;AAAA,EAER;AAAA,EACT,UAAkC;AAAA,EAClC,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,SAAmB,CAAA;AAAA;AAAA;AAAA;AAAA,EAK3B,YAAYC,GAA0B;AAEpC,SAAK,SAAS,OAAOA,KAAY,WAC7B,IAAI,OAAOA,GAAS,GAAG,IACvB,IAAI,OAAOA,EAAQ,QAAQA,EAAQ,MAAM,SAAS,GAAG,IAAIA,EAAQ,QAAQ,GAAGA,EAAQ,KAAK,GAAG;AAAA,EAClG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,MAAMC,GAAmB;AAC9B,SAAK,MAAMA,GACX,KAAK,UAAU,MACf,KAAK,iBAAiB,GACtB,KAAK,YAAY,IACjB,KAAK,SAAS,CAAA,GACd,KAAK,OAAO,YAAY;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,OAAgB;AACrB,QAAI,KAAK;AACP,aAAO;AAGT,QADA,KAAK,UAAU,KAAK,OAAO,KAAK,KAAK,GAAG,GACpC,CAAC,KAAK;AAER,kBAAK,YAAY,IACV;AAET,QAAI,KAAK,QAAQ,CAAC,MAAM,IAAI;AAG1B,YAAMC,IAAY,OAAO,KAAK,KAAK,OAAO,KAAK,GACzCC,IAAY,KAAK,IAAI,YAAY,KAAK,OAAO,SAAS;AAC5D,WAAK,OAAO,aAAaD,KAAaC,MAAc,UAAaA,IAAY,QAAS,IAAI;AAAA,IAC5F;AACA,WAAO;AAAA,EACT;AAAA,EAYO,MAAMC,IAAQ,GAAkB;AACrC,UAAMC,IAAU,KAAK,eAAA;AACrB,QAAID,IAAQ,KAAKC,EAAQ,UAAUD;AACjC,YAAM,IAAI,WAAW,YAAYA,CAAK,EAAE;AAE1C,WAAOC,EAAQD,CAAK,KAAK;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,aAAqC;AAC1C,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,kBAAkBE,GAAsBC,GAAuD;AACpG,UAAMF,IAAU,KAAK,eAAA;AACrB,QAAIA,EAAQ,QAAQ,KAAK;AACvB,YAAM,IAAI,WAAW,iEAAiE;AAExF,UAAMG,IAAW,KAAK,IAAI,MAAM,KAAK,gBAAgBH,EAAQ,KAAK;AAClE,SAAK,OAAO,KAAKE,IAAmBA,EAAiBC,CAAQ,IAAIA,CAAQ,GACzE,KAAK,OAAO,KAAK,OAAOF,KAAY,aAAaA,EAAQD,CAAO,IAAIC,CAAO,GAC3E,KAAK,iBAAiBD,EAAQ,QAAQA,EAAQ,CAAC,EAAE;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,WAAWI,GAA+C;AAC/D,UAAMC,IAAO,KAAK,IAAI,MAAM,KAAK,cAAc;AAC/C,SAAK,OAAO,KAAKD,IAAeA,EAAaC,CAAI,IAAIA,CAAI;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,WAAmB;AACxB,WAAO,KAAK,OAAO,KAAK,EAAE;AAAA,EAC5B;AAAA,EAEQ,iBAAkC;AACxC,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,oBAAoB;AAEtC,WAAO,KAAK;AAAA,EACd;AACF;"}
|
package/src/reg-exp-matcher.ts
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 置換文字列、または現在のマッチ情報から置換文字列を返す関数
|
|
3
|
-
*/
|
|
4
|
-
export type Replacement = string | ((matcher: RegExpExecArray) => string);
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* マッチ箇所ごとに置換内容を決めながら文字列を組み立てる。
|
|
8
|
-
*
|
|
9
|
-
* 例)
|
|
10
|
-
* const regExpMatcher = new RegExpMatcher(/\:([^/?]+)/g);
|
|
11
|
-
* regExpMatcher.reset('/EWM/WalletID/:WalletID/Job/:JobID');
|
|
12
|
-
* while (regExpMatcher.find()) {
|
|
13
|
-
* const match = regExpMatcher.group();
|
|
14
|
-
* if (match === ':WalletID') {
|
|
15
|
-
* regExpMatcher.appendReplacement('12345');
|
|
16
|
-
* }
|
|
17
|
-
* if (match === ':JobID') {
|
|
18
|
-
* regExpMatcher.appendReplacement('99999999');
|
|
19
|
-
* }
|
|
20
|
-
* }
|
|
21
|
-
* regExpMatcher.appendTail();
|
|
22
|
-
* regExpMatcher.toString(); // '/EWM/WalletID/12345/Job/99999999'
|
|
23
|
-
*/
|
|
24
|
-
export class RegExpMatcher {
|
|
25
|
-
|
|
26
|
-
private readonly regexp: RegExp;
|
|
27
|
-
private matcher: RegExpExecArray | null = null;
|
|
28
|
-
private str = '';
|
|
29
|
-
private appendPosition = 0;
|
|
30
|
-
private exhausted = false;
|
|
31
|
-
private buffer: string[] = [];
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* @param {string | RegExp} pattern 文字列の場合はglobal属性を付与して解釈する。RegExpの場合はglobal属性の有無を問わない
|
|
35
|
-
*/
|
|
36
|
-
constructor(pattern: string | RegExp) {
|
|
37
|
-
// 走査にはglobal属性が必要。呼び出し側のRegExpのlastIndexを汚さないよう、渡されたRegExpは使わず複製する
|
|
38
|
-
this.regexp = typeof pattern === 'string'
|
|
39
|
-
? new RegExp(pattern, 'g')
|
|
40
|
-
: new RegExp(pattern.source, pattern.flags.includes('g') ? pattern.flags : `${pattern.flags}g`);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* 走査対象の文字列を設定し、走査位置とバッファを先頭に戻す
|
|
45
|
-
*
|
|
46
|
-
* @param {string} str
|
|
47
|
-
*/
|
|
48
|
-
public reset(str: string): void {
|
|
49
|
-
this.str = str;
|
|
50
|
-
this.matcher = null;
|
|
51
|
-
this.appendPosition = 0;
|
|
52
|
-
this.exhausted = false;
|
|
53
|
-
this.buffer = [];
|
|
54
|
-
this.regexp.lastIndex = 0;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* 次のマッチ箇所へ進める
|
|
59
|
-
* これ以上マッチしなくなった後は、reset()するまでfalseを返し続ける
|
|
60
|
-
*
|
|
61
|
-
* @returns {boolean} マッチした場合はtrue
|
|
62
|
-
*/
|
|
63
|
-
public find(): boolean {
|
|
64
|
-
if (this.exhausted) {
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
this.matcher = this.regexp.exec(this.str);
|
|
68
|
-
if (!this.matcher) {
|
|
69
|
-
// execは失敗するとlastIndexを0に戻し、次の呼び出しで先頭から再びマッチしてしまうため、走査済みとして止める
|
|
70
|
-
this.exhausted = true;
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
if (this.matcher[0] === '') {
|
|
74
|
-
// 空文字にマッチするとlastIndexが進まず同じ位置を繰り返すため、1文字(u/v属性ありならコードポイント1つ)進める
|
|
75
|
-
// v属性ではunicodeがfalseになるためflagsで判定する。サロゲートペアの途中から走査すると先頭に戻ってしまい無限ループになる
|
|
76
|
-
const isUnicode = /[uv]/.test(this.regexp.flags);
|
|
77
|
-
const codePoint = this.str.codePointAt(this.regexp.lastIndex);
|
|
78
|
-
this.regexp.lastIndex += isUnicode && codePoint !== undefined && codePoint > 0xffff ? 2 : 1;
|
|
79
|
-
}
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* 現在のマッチ文字列を返す
|
|
85
|
-
*
|
|
86
|
-
* @param {number} [index] キャプチャグループの番号。省略時はマッチ全体
|
|
87
|
-
* @returns {string | null} グループがマッチに参加しなかった場合はnull
|
|
88
|
-
* @throws {Error} マッチしていない場合
|
|
89
|
-
* @throws {RangeError} 存在しないグループ番号を指定した場合
|
|
90
|
-
*/
|
|
91
|
-
public group(): string;
|
|
92
|
-
public group(index: number): string | null;
|
|
93
|
-
public group(index = 0): string | null {
|
|
94
|
-
const matcher = this.currentMatcher();
|
|
95
|
-
if (index < 0 || matcher.length <= index) {
|
|
96
|
-
throw new RangeError(`No group ${index}`);
|
|
97
|
-
}
|
|
98
|
-
return matcher[index] ?? null;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* 現在のマッチ情報を返す
|
|
103
|
-
*
|
|
104
|
-
* @returns {RegExpExecArray | null} マッチしていない場合はnull
|
|
105
|
-
*/
|
|
106
|
-
public getMatcher(): RegExpExecArray | null {
|
|
107
|
-
return this.matcher;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* 前回の置換位置から現在のマッチ箇所までの不一致文字列と、マッチ箇所の置換文字列をバッファに追加する
|
|
112
|
-
*
|
|
113
|
-
* @param {Replacement} replace 置換文字列、または置換関数。置換文字列の `$1` などは解釈せずそのまま出力するため、グループを参照する場合は置換関数を渡す
|
|
114
|
-
* @param {(notMatch: string) => string} [notMatchReplacer] 不一致文字列の置換関数
|
|
115
|
-
* @throws {Error} マッチしていない場合
|
|
116
|
-
* @throws {RangeError} 現在のマッチに対して既に呼び出している場合
|
|
117
|
-
*/
|
|
118
|
-
public appendReplacement(replace: Replacement, notMatchReplacer?: (notMatch: string) => string): void {
|
|
119
|
-
const matcher = this.currentMatcher();
|
|
120
|
-
if (matcher.index < this.appendPosition) {
|
|
121
|
-
throw new RangeError('appendReplacement has already been called for the current match');
|
|
122
|
-
}
|
|
123
|
-
const notMatch = this.str.slice(this.appendPosition, matcher.index);
|
|
124
|
-
this.buffer.push(notMatchReplacer ? notMatchReplacer(notMatch) : notMatch);
|
|
125
|
-
this.buffer.push(typeof replace === 'function' ? replace(matcher) : replace);
|
|
126
|
-
this.appendPosition = matcher.index + matcher[0].length;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* 前回の置換位置から末尾までの文字列をバッファに追加する
|
|
131
|
-
*
|
|
132
|
-
* @param {(tail: string) => string} [tailReplacer] 末尾文字列の置換関数
|
|
133
|
-
*/
|
|
134
|
-
public appendTail(tailReplacer?: (tail: string) => string): void {
|
|
135
|
-
const tail = this.str.slice(this.appendPosition);
|
|
136
|
-
this.buffer.push(tailReplacer ? tailReplacer(tail) : tail);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* バッファに追加した文字列を連結して返す
|
|
141
|
-
*
|
|
142
|
-
* @returns {string}
|
|
143
|
-
*/
|
|
144
|
-
public toString(): string {
|
|
145
|
-
return this.buffer.join('');
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
private currentMatcher(): RegExpExecArray {
|
|
149
|
-
if (!this.matcher) {
|
|
150
|
-
throw new Error('No match available');
|
|
151
|
-
}
|
|
152
|
-
return this.matcher;
|
|
153
|
-
}
|
|
154
|
-
}
|