-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBREGEXP.hsp
257 lines (209 loc) · 8.51 KB
/
BREGEXP.hsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
/* BREGEXP.hsp */
#ifndef mod_BRegExp
#module mod_BRegExp
#uselib "BREGEXP.DLL"
// #uselib "BREGONIG.DLL"
////////////////////////////////////////////////////////
// BREGEXP.DLL モジュール Ver 1.01 by 猫太→月影とも//
////////////////////////////////////////////////////////
// 2008.10.18 v1.01 ヘルプとサンプルがそれぞれビミョーに間違ってたので修正
// 2006. 9.29 v1.00 公開
//// 以下の命令を追加する。
//// **** マッチ関連関数 ****
////
//// BMatch(対象変数, 開始位置, "m/~/[k][m]")
//// 正規表現によるパターンマッチを行い、マッチした位置を返す。
//// デフォルトではInstr互換モードで開始位置からの相対位置を返す。
//// 常に先頭からの位置を返すようにも設定可能 → BRegInstrCompatibleMode 0
//// kを付けると、文字列をSJisとして処理
////
//// 以下の関数群は、BMatch後、対象変数の内容が変更されるまで有効。
//// エラーチェックをしていないので注意。
//// n = 0 のとき全体、n = 1,2,3... のとき、n番目の()内を対象とする
////
//// BMGetStr(n)
//// BMatchのパターンにおいてマッチした文字列を返す
////
//// BMGetPos(n)
//// BMatchのパターンにおいてマッチした文字列の位置を返す
//// Instr互換モードの設定の影響を受ける。
////
//// BMGetLen(n)
//// BMatchのパターンにおいてマッチした文字列の長さを返す
////
//// BMGetNextPos()
//// 次に設定すべき検索開始位置を返す。
//// Instr互換モードの影響を受ける。
////
////
////
//// **** 他の命令群 置換/変換/文字列分割 ****
////
//// BSubst 対象変数, "s/~/―/[k][m][g]"
//// 置換を行った回数が stat に返る
////
//// BTrans 対象変数, "tr/~/―/[k][m][c][d][s]"
//// stat に 変換を行った回数が返る
////
//// BSplit 出力先配列変数, 対象変数, "m/~/[k][m]"
//// PatternTextをデリミタとした文字列の分割。
//// 要素数が stat に返る。
////
//// BRegexpVersion
//// refstr にバージョン文字列が返る
////
//// BRegGetErrorMsg
//// refstr に最後に行った処理に対するエラー文字列が返る
////
//// BRegInstrCompatibleMode 0/1
//// BMatch 関連関数の Instr互換モードの設定。
//// 1: instr互換(検索開始位置からの相対位置) - デフォルト
//// 0: 常に文字列変数先頭からの位置を返す
////
#func _BMatch "BMatch" sptr,int,int,sptr,int
#func _BSubst "BSubst" sptr,int,int,sptr,int
#func _BTrans "BTrans" sptr,int,int,sptr,int
#func _BSplit "BSplit" sptr,int,int,int,sptr,int
#func _BRegfree "BRegfree" int
#func _BRegexpVersion "BRegexpVersion"
#if 0
typedef struct bregexp {
0 const char *outp; // BSubst 置換データの先頭ポインタ
1 const char *outendp; // BSubst 置換データの最終ポインタ+1
2 const int splitctr; // BSplit 配列数
3 const char **splitp; // BSplit データポインタ
4 int rsv1; // リザーブ 自由に使用可能
5 char *parap; // パターンデータポインタ
6 char *paraendp; // パターンデータポインタ1
7 char *transtblp; // BTrans 変換テーブルポインタ
8 char **startp; // マッチしたデータの先頭ポインタ
9 char **endp; // マッチしたデータの最終ポインタ+1
10 int nparens; // パターンの中の() の数。 $1,$2, を調べるときに使用
} BREGEXP;
#endif
#deffunc BReg_SafeFree int _ptr // 解放 基本的に内部命令。
if _ptr : _BRegfree _ptr
return
#defcfunc BMatch var target, int StartPostion, str PatternText
BReg_SafeFree pBregExp : pBregExp = 0 ;// NULL
pattern = PatternText
startPos = StartPostion
_BMatch varptr(pattern), varptr(target)+startPos, varptr(target)+strlen(target), varptr(pBregExp), varptr(BM_err_info)
if stat <= 0 : return -1
dupptr BregExp, pBregExp, 44, vartype("int")
dup TargetString, target
BregExp_nParens = BregExp.10
dupptr BregExp_StartP, BregExp.8, BregExp.10*4+4, vartype("int")
dupptr BregExp_EndP, BregExp.9, BregExp.10*4+4, vartype("int")
return BregExp_StartP - varptr(target) - startPos*CompatiMode
#defcfunc BMGetStr int i
if pBregExp = 0 : dialog "BREGEXP Error:\n 直前の操作がBMatchではありません" : return ""
if i>BregExp_nParens : return ""
return strmid(TargetString, BregExp_StartP.i - varptr(TargetString), BregExp_EndP.i - BregExp_StartP.i)
#defcfunc BMGetPos int i
if pBregExp = 0 : dialog "BREGEXP Error:\n 直前の操作がBMatchではありません" : return -1
if i>BregExp_nParens : return -1
return BregExp_StartP.i - varptr(TargetString) - startPos*CompatiMode
#defcfunc BMGetLen int i
if pBregExp = 0 : dialog "BREGEXP Error:\n 直前の操作がBMatchではありません" : return -1
if i>BregExp_nParens : return -1
return BregExp_EndP.i - BregExp_StartP.i
#defcfunc BMGetNextPos
if pBregExp = 0 : dialog "BREGEXP Error:\n 直前の操作がBMatchではありません" : return -1
return BregExp_EndP.0 - varptr(TargetString) - startPos*CompatiMode
#deffunc BSubst var target, str PatternText, local output
BReg_SafeFree pBregExp : pBregExp = 0 ;// NULL
pattern = PatternText
if peek(pattern,0) ! 's' {
dialog "BREGEXP Error:\n BSubstのパターンは 's/~/~/' の形式で書いてください。 \nPatternText: "+PatternText
return -1
}
_BSubst varptr(pattern), varptr(target), varptr(target)+strlen(target), varptr(pBregExp), varptr(BM_err_info)
if stat : count = stat : else : return 0
dupptr BregExp, pBregExp, 44, vartype("int")
dupptr output, BregExp.0, BregExp.1 - BregExp.0,vartype("str")
target = strmid(output, 0, BregExp.1 - BregExp.0)
BReg_SafeFree pBregExp : pBregExp = 0 ;// NULL
return count
#deffunc BTrans var target, str PatternText, local output
BReg_SafeFree pBregExp : pBregExp = 0 ;// NULL
pattern = PatternText
if peek(pattern,0) ! 't' | peek(pattern,1) ! 'r' {
dialog "BREGEXP Error:\n BSubstのパターンは 'tr/~/~/' の形式で書いてください。 \nPatternText: "+PatternText
return -1
}
_BTrans varptr(pattern), varptr(target), varptr(target)+strlen(target), varptr(pBregExp), varptr(BM_err_info)
if stat : count = stat : else : return 0
dupptr BregExp, pBregExp, 44, vartype("int")
dupptr output, BregExp.0, BregExp.1 - BregExp.0,vartype("str")
target = strmid(output, 0, BregExp.1 - BregExp.0)
BReg_SafeFree pBregExp : pBregExp = 0 ;// NULL
return count
#deffunc BSplit array Output, var target, str PatternText, int MaxCount
BReg_SafeFree pBregExp : pBregExp = 0 ;// NULL
sdim output,64
pattern = PatternText
_BSplit varptr(pattern), varptr(target), varptr(target)+strlen(target), MaxCount, varptr(pBregExp), varptr(BM_err_info)
if stat : count = stat : else : return 0
dupptr BregExp, pBregExp, 44, vartype("int")
dupptr ptr, BregExp.3, 8*count, vartype("int")
repeat count
output.cnt = strmid(target, ptr(cnt*2)-varptr(target), ptr(cnt*2+1)-ptr(cnt*2))
loop
BReg_SafeFree pBregExp : pBregExp = 0 ;// NULL
return count
#deffunc BRegexpVersion
_BRegexpVersion
return strf("%s",stat)
#deffunc initBRegExp@mod_BRegExp
sdim BM_err_info, 80
CompatiMode = 1
return
#deffunc deInitBRegExp@mod_BRegExp onexit
BReg_SafeFree pBRegExp
return
#defcfunc BRegGetErrorMsg
return BM_err_info
#deffunc BRegInstrCompatibleMode int i
if i : CompatiMode = 1 : else : CompatiMode = 0
return
#global
initBRegExp@mod_BRegExp
#endif
#if 0 //////////////////////// テスト&サンプル
pos 10,10
BRegexpVersion
mes refstr
mes
target = "本日は晴天なり!"
mes "target = \"本日は晴天なり!\""
s = BMatch(target, 0, "m/は(.*?)な(.*?)!/")
mes "BMatch(target, 0, \"m/は(.*?)な(.*?)!/\") :" + s
// 以下直前マッチの結果を返す。注意:targetの文字列が変更されるまで有効
mes "BMGetStr(0) : "+ BMGetStr(0) // マッチした文字列そのもの
mes "BMGetStr(1) : "+ BMGetStr(1) // 左から1番目の( )の中身 RegExp.$1に該当
mes "BMGetStr(2) : "+ BMGetStr(2) // 左から2番目の( )の中身 RegExp.$2に該当
mes "BMGetPos(2) : "+ BMGetPos(2) // 左から2番目の( )の位置
mes "BMGetLen(2) : "+ BMGetLen(2) // 左から2番目の( )の位置
mes
target = "本日は晴天なり!"
BSubst target, "s/^(.*?)は(.*?)な(.*?)$/[$1]は[$2]のような[$3]です。/g"
mes target
target = "This is a pen."
BSubst target, "s/is/XX/"
mes target
target = "This is a pen."
BSubst target, "s/is/XX/g"
mes target
target = "abcdefg012345opqrs"
BTrans target, "tr/a-z0-9/A-Z_/"
mes target
target = "アイウエオカキクケコ"
BTrans target, "tr/0-9/A-Z/"
mes target
target = "あ,か,さ,た,な"
BSplit list, target, "/,/"
repeat stat
mes "list."+cnt+ " : "+list.cnt
loop
#endif