react-util-tools 1.0.25 → 1.0.26
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 +38 -0
- package/dist/index.cjs +317 -0
- package/dist/index.d.cts +45 -1
- package/dist/index.d.ts +45 -1
- package/dist/index.js +274 -0
- package/package.json +1 -1
- package/src/index.ts +45 -0
- package/src/string/README.md +441 -0
- package/src/string/index.ts +527 -0
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
# String - 字符串工具
|
|
2
|
+
|
|
3
|
+
强大的字符串处理工具集合,包含命名转换、格式化、验证、脱敏等常用功能。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- 🔤 命名转换(驼峰、蛇形、短横线等)
|
|
8
|
+
- ✂️ 字符串操作(截断、填充、反转等)
|
|
9
|
+
- 🔒 数据脱敏(手机号、身份证、银行卡等)
|
|
10
|
+
- ✅ 格式验证(手机号、邮箱、URL 等)
|
|
11
|
+
- 🎲 随机字符串生成
|
|
12
|
+
- 🔐 Base64 编解码
|
|
13
|
+
- 🧹 HTML 转义/反转义
|
|
14
|
+
|
|
15
|
+
## 安装
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install react-util-tools
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 使用示例
|
|
22
|
+
|
|
23
|
+
### 命名转换
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import {
|
|
27
|
+
camelCase,
|
|
28
|
+
pascalCase,
|
|
29
|
+
snakeCase,
|
|
30
|
+
kebabCase
|
|
31
|
+
} from 'react-util-tools'
|
|
32
|
+
|
|
33
|
+
// 驼峰命名(首字母小写)
|
|
34
|
+
camelCase('hello-world') // 'helloWorld'
|
|
35
|
+
camelCase('hello_world') // 'helloWorld'
|
|
36
|
+
camelCase('Hello World') // 'helloWorld'
|
|
37
|
+
|
|
38
|
+
// 帕斯卡命名(首字母大写)
|
|
39
|
+
pascalCase('hello-world') // 'HelloWorld'
|
|
40
|
+
pascalCase('hello_world') // 'HelloWorld'
|
|
41
|
+
|
|
42
|
+
// 蛇形命名(下划线)
|
|
43
|
+
snakeCase('helloWorld') // 'hello_world'
|
|
44
|
+
snakeCase('HelloWorld') // 'hello_world'
|
|
45
|
+
|
|
46
|
+
// 短横线命名(kebab-case)
|
|
47
|
+
kebabCase('helloWorld') // 'hello-world'
|
|
48
|
+
kebabCase('HelloWorld') // 'hello-world'
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 字符串操作
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import {
|
|
55
|
+
capitalize,
|
|
56
|
+
titleCase,
|
|
57
|
+
truncate,
|
|
58
|
+
reverse,
|
|
59
|
+
repeat,
|
|
60
|
+
padStart,
|
|
61
|
+
padEnd
|
|
62
|
+
} from 'react-util-tools'
|
|
63
|
+
|
|
64
|
+
// 首字母大写
|
|
65
|
+
capitalize('hello') // 'Hello'
|
|
66
|
+
|
|
67
|
+
// 单词首字母大写
|
|
68
|
+
titleCase('hello world') // 'Hello World'
|
|
69
|
+
|
|
70
|
+
// 截断字符串
|
|
71
|
+
truncate('Hello World', 5) // 'Hello...'
|
|
72
|
+
truncate('Hello World', 5, '~') // 'Hello~'
|
|
73
|
+
|
|
74
|
+
// 反转字符串
|
|
75
|
+
reverse('hello') // 'olleh'
|
|
76
|
+
|
|
77
|
+
// 重复字符串
|
|
78
|
+
repeat('ab', 3) // 'ababab'
|
|
79
|
+
|
|
80
|
+
// 填充字符串
|
|
81
|
+
padStart('5', 3, '0') // '005'
|
|
82
|
+
padEnd('5', 3, '0') // '500'
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 数据脱敏
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import {
|
|
89
|
+
maskPhone,
|
|
90
|
+
maskIdCard,
|
|
91
|
+
maskBankCard,
|
|
92
|
+
maskName,
|
|
93
|
+
maskEmail
|
|
94
|
+
} from 'react-util-tools'
|
|
95
|
+
|
|
96
|
+
// 手机号脱敏
|
|
97
|
+
maskPhone('13812345678') // '138****5678'
|
|
98
|
+
|
|
99
|
+
// 身份证号脱敏
|
|
100
|
+
maskIdCard('110101199001011234') // '110101********1234'
|
|
101
|
+
|
|
102
|
+
// 银行卡号脱敏
|
|
103
|
+
maskBankCard('6222021234567890') // '6222 **** **** 7890'
|
|
104
|
+
|
|
105
|
+
// 姓名脱敏
|
|
106
|
+
maskName('张三') // '张*'
|
|
107
|
+
maskName('李四光') // '李*光'
|
|
108
|
+
|
|
109
|
+
// 邮箱脱敏(在 format 模块)
|
|
110
|
+
maskEmail('test@example.com') // 'tes***@example.com'
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 格式验证
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import {
|
|
117
|
+
isValidPhone,
|
|
118
|
+
isValidEmail,
|
|
119
|
+
isValidUrl,
|
|
120
|
+
isValidIdCard
|
|
121
|
+
} from 'react-util-tools'
|
|
122
|
+
|
|
123
|
+
// 验证手机号(中国大陆)
|
|
124
|
+
isValidPhone('13812345678') // true
|
|
125
|
+
isValidPhone('12345678901') // false
|
|
126
|
+
|
|
127
|
+
// 验证邮箱
|
|
128
|
+
isValidEmail('test@example.com') // true
|
|
129
|
+
isValidEmail('invalid-email') // false
|
|
130
|
+
|
|
131
|
+
// 验证 URL
|
|
132
|
+
isValidUrl('https://example.com') // true
|
|
133
|
+
isValidUrl('not-a-url') // false
|
|
134
|
+
|
|
135
|
+
// 验证身份证号(中国大陆)
|
|
136
|
+
isValidIdCard('110101199001011234') // true
|
|
137
|
+
isValidIdCard('123456') // false
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 字符串查询
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import {
|
|
144
|
+
startsWith,
|
|
145
|
+
endsWith,
|
|
146
|
+
includes,
|
|
147
|
+
countOccurrences,
|
|
148
|
+
isEmpty,
|
|
149
|
+
isNotEmpty
|
|
150
|
+
} from 'react-util-tools'
|
|
151
|
+
|
|
152
|
+
// 判断开头
|
|
153
|
+
startsWith('hello world', 'hello') // true
|
|
154
|
+
|
|
155
|
+
// 判断结尾
|
|
156
|
+
endsWith('hello world', 'world') // true
|
|
157
|
+
|
|
158
|
+
// 判断包含
|
|
159
|
+
includes('hello world', 'lo wo') // true
|
|
160
|
+
|
|
161
|
+
// 计算出现次数
|
|
162
|
+
countOccurrences('hello hello', 'hello') // 2
|
|
163
|
+
|
|
164
|
+
// 判断是否为空
|
|
165
|
+
isEmpty('') // true
|
|
166
|
+
isEmpty(' ') // true
|
|
167
|
+
isEmpty('hello') // false
|
|
168
|
+
|
|
169
|
+
// 判断是否不为空
|
|
170
|
+
isNotEmpty('hello') // true
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### HTML 处理
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import {
|
|
177
|
+
stripHtml,
|
|
178
|
+
escapeHtml,
|
|
179
|
+
unescapeHtml
|
|
180
|
+
} from 'react-util-tools'
|
|
181
|
+
|
|
182
|
+
// 移除 HTML 标签
|
|
183
|
+
stripHtml('<p>Hello <strong>World</strong></p>') // 'Hello World'
|
|
184
|
+
|
|
185
|
+
// 转义 HTML
|
|
186
|
+
escapeHtml('<div>Hello & "World"</div>')
|
|
187
|
+
// '<div>Hello & "World"</div>'
|
|
188
|
+
|
|
189
|
+
// 反转义 HTML
|
|
190
|
+
unescapeHtml('<div>Hello</div>') // '<div>Hello</div>'
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### 随机字符串
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
import { randomString, uuid } from 'react-util-tools'
|
|
197
|
+
|
|
198
|
+
// 生成随机字符串
|
|
199
|
+
randomString(8) // 'aB3xY9Zk'
|
|
200
|
+
randomString(6, '0123456789') // '482916'
|
|
201
|
+
|
|
202
|
+
// 生成 UUID
|
|
203
|
+
uuid() // '550e8400-e29b-41d4-a716-446655440000'
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Base64 编解码
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
import { toBase64, fromBase64 } from 'react-util-tools'
|
|
210
|
+
|
|
211
|
+
// 编码
|
|
212
|
+
const encoded = toBase64('Hello World') // 'SGVsbG8gV29ybGQ='
|
|
213
|
+
|
|
214
|
+
// 解码
|
|
215
|
+
const decoded = fromBase64(encoded) // 'Hello World'
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### 空格处理
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
import {
|
|
222
|
+
trim,
|
|
223
|
+
trimStart,
|
|
224
|
+
trimEnd,
|
|
225
|
+
removeSpaces,
|
|
226
|
+
normalizeSpaces
|
|
227
|
+
} from 'react-util-tools'
|
|
228
|
+
|
|
229
|
+
// 移除两端空格
|
|
230
|
+
trim(' hello ') // 'hello'
|
|
231
|
+
|
|
232
|
+
// 移除左侧空格
|
|
233
|
+
trimStart(' hello') // 'hello'
|
|
234
|
+
|
|
235
|
+
// 移除右侧空格
|
|
236
|
+
trimEnd('hello ') // 'hello'
|
|
237
|
+
|
|
238
|
+
// 移除所有空格
|
|
239
|
+
removeSpaces('h e l l o') // 'hello'
|
|
240
|
+
|
|
241
|
+
// 规范化空格(多个空格变为一个)
|
|
242
|
+
normalizeSpaces('hello world') // 'hello world'
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### 字符串替换
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
import { replaceAll } from 'react-util-tools'
|
|
249
|
+
|
|
250
|
+
// 替换所有匹配项
|
|
251
|
+
replaceAll('hello hello', 'hello', 'hi') // 'hi hi'
|
|
252
|
+
|
|
253
|
+
// 使用正则表达式
|
|
254
|
+
replaceAll('hello123world456', /\d+/g, 'X') // 'helloXworldX'
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### 提取数字
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
import { extractNumbers } from 'react-util-tools'
|
|
261
|
+
|
|
262
|
+
// 提取所有数字
|
|
263
|
+
extractNumbers('价格: 99.99元, 数量: 5个') // [99.99, 5]
|
|
264
|
+
extractNumbers('abc123def456') // [123, 456]
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## API 参考
|
|
268
|
+
|
|
269
|
+
### 命名转换
|
|
270
|
+
|
|
271
|
+
- `capitalize(str)` - 首字母大写
|
|
272
|
+
- `camelCase(str)` - 驼峰命名(首字母小写)
|
|
273
|
+
- `pascalCase(str)` - 帕斯卡命名(首字母大写)
|
|
274
|
+
- `snakeCase(str)` - 蛇形命名(下划线)
|
|
275
|
+
- `kebabCase(str)` - 短横线命名
|
|
276
|
+
- `titleCase(str)` - 单词首字母大写
|
|
277
|
+
|
|
278
|
+
### 字符串操作
|
|
279
|
+
|
|
280
|
+
- `truncate(str, length, suffix?)` - 截断字符串
|
|
281
|
+
- `trim(str)` - 移除两端空格
|
|
282
|
+
- `trimStart(str)` - 移除左侧空格
|
|
283
|
+
- `trimEnd(str)` - 移除右侧空格
|
|
284
|
+
- `reverse(str)` - 反转字符串
|
|
285
|
+
- `repeat(str, count)` - 重复字符串
|
|
286
|
+
- `padStart(str, length, padStr?)` - 左侧填充
|
|
287
|
+
- `padEnd(str, length, padStr?)` - 右侧填充
|
|
288
|
+
- `toLowerCase(str)` - 转小写
|
|
289
|
+
- `toUpperCase(str)` - 转大写
|
|
290
|
+
|
|
291
|
+
### 字符串查询
|
|
292
|
+
|
|
293
|
+
- `startsWith(str, searchString)` - 判断开头
|
|
294
|
+
- `endsWith(str, searchString)` - 判断结尾
|
|
295
|
+
- `includes(str, searchString)` - 判断包含
|
|
296
|
+
- `isEmpty(str)` - 判断是否为空
|
|
297
|
+
- `isNotEmpty(str)` - 判断是否不为空
|
|
298
|
+
- `length(str)` - 获取长度(支持 Unicode)
|
|
299
|
+
- `countOccurrences(str, searchString)` - 计算出现次数
|
|
300
|
+
|
|
301
|
+
### 字符串处理
|
|
302
|
+
|
|
303
|
+
- `split(str, separator)` - 分割字符串
|
|
304
|
+
- `replaceAll(str, search, replacement)` - 替换所有匹配项
|
|
305
|
+
- `removeSpaces(str)` - 移除所有空格
|
|
306
|
+
- `normalizeSpaces(str)` - 规范化空格
|
|
307
|
+
- `extractNumbers(str)` - 提取数字
|
|
308
|
+
|
|
309
|
+
### HTML 处理
|
|
310
|
+
|
|
311
|
+
- `stripHtml(str)` - 移除 HTML 标签
|
|
312
|
+
- `escapeHtml(str)` - 转义 HTML
|
|
313
|
+
- `unescapeHtml(str)` - 反转义 HTML
|
|
314
|
+
|
|
315
|
+
### 数据脱敏
|
|
316
|
+
|
|
317
|
+
- `maskPhone(phone)` - 手机号脱敏
|
|
318
|
+
- `maskIdCard(idCard)` - 身份证号脱敏
|
|
319
|
+
- `maskBankCard(cardNumber)` - 银行卡号脱敏
|
|
320
|
+
- `maskName(name)` - 姓名脱敏
|
|
321
|
+
|
|
322
|
+
### 格式验证
|
|
323
|
+
|
|
324
|
+
- `isValidPhone(phone)` - 验证手机号
|
|
325
|
+
- `isValidEmail(email)` - 验证邮箱
|
|
326
|
+
- `isValidUrl(url)` - 验证 URL
|
|
327
|
+
- `isValidIdCard(idCard)` - 验证身份证号
|
|
328
|
+
|
|
329
|
+
### 随机生成
|
|
330
|
+
|
|
331
|
+
- `randomString(length, chars?)` - 生成随机字符串
|
|
332
|
+
- `uuid()` - 生成 UUID v4
|
|
333
|
+
|
|
334
|
+
### Base64
|
|
335
|
+
|
|
336
|
+
- `toBase64(str)` - 字符串转 Base64
|
|
337
|
+
- `fromBase64(base64)` - Base64 转字符串
|
|
338
|
+
|
|
339
|
+
## TypeScript 支持
|
|
340
|
+
|
|
341
|
+
完整的 TypeScript 类型定义:
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
import {
|
|
345
|
+
camelCase,
|
|
346
|
+
maskPhone,
|
|
347
|
+
isValidEmail,
|
|
348
|
+
randomString
|
|
349
|
+
} from 'react-util-tools'
|
|
350
|
+
|
|
351
|
+
const name: string = camelCase('hello-world')
|
|
352
|
+
const phone: string = maskPhone('13812345678')
|
|
353
|
+
const valid: boolean = isValidEmail('test@example.com')
|
|
354
|
+
const random: string = randomString(10)
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## 注意事项
|
|
358
|
+
|
|
359
|
+
1. **手机号验证**:仅支持中国大陆手机号格式
|
|
360
|
+
2. **身份证验证**:仅支持中国大陆身份证号格式
|
|
361
|
+
3. **Base64 编解码**:支持浏览器和 Node.js 环境
|
|
362
|
+
4. **Unicode 支持**:`length()` 函数正确处理 Unicode 字符
|
|
363
|
+
5. **HTML 转义**:仅转义常见的特殊字符
|
|
364
|
+
|
|
365
|
+
## 实际应用场景
|
|
366
|
+
|
|
367
|
+
### 表单验证
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
import { isValidPhone, isValidEmail } from 'react-util-tools'
|
|
371
|
+
|
|
372
|
+
function validateForm(data: any) {
|
|
373
|
+
const errors: any = {}
|
|
374
|
+
|
|
375
|
+
if (!isValidPhone(data.phone)) {
|
|
376
|
+
errors.phone = '请输入有效的手机号'
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (!isValidEmail(data.email)) {
|
|
380
|
+
errors.email = '请输入有效的邮箱'
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
return errors
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### 数据展示脱敏
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
import { maskPhone, maskIdCard } from 'react-util-tools'
|
|
391
|
+
|
|
392
|
+
function UserInfo({ user }: any) {
|
|
393
|
+
return (
|
|
394
|
+
<div>
|
|
395
|
+
<p>手机号: {maskPhone(user.phone)}</p>
|
|
396
|
+
<p>身份证: {maskIdCard(user.idCard)}</p>
|
|
397
|
+
</div>
|
|
398
|
+
)
|
|
399
|
+
}
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### API 字段转换
|
|
403
|
+
|
|
404
|
+
```typescript
|
|
405
|
+
import { camelCase, snakeCase } from 'react-util-tools'
|
|
406
|
+
|
|
407
|
+
// 后端返回的蛇形命名转驼峰
|
|
408
|
+
function transformResponse(data: any) {
|
|
409
|
+
const result: any = {}
|
|
410
|
+
for (const key in data) {
|
|
411
|
+
result[camelCase(key)] = data[key]
|
|
412
|
+
}
|
|
413
|
+
return result
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// 前端驼峰命名转蛇形发送给后端
|
|
417
|
+
function transformRequest(data: any) {
|
|
418
|
+
const result: any = {}
|
|
419
|
+
for (const key in data) {
|
|
420
|
+
result[snakeCase(key)] = data[key]
|
|
421
|
+
}
|
|
422
|
+
return result
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### 生成唯一标识
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
import { uuid, randomString } from 'react-util-tools'
|
|
430
|
+
|
|
431
|
+
// 生成订单号
|
|
432
|
+
function generateOrderId() {
|
|
433
|
+
return `ORDER-${Date.now()}-${randomString(6, '0123456789')}`
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// 生成文件名
|
|
437
|
+
function generateFileName(originalName: string) {
|
|
438
|
+
const ext = originalName.split('.').pop()
|
|
439
|
+
return `${uuid()}.${ext}`
|
|
440
|
+
}
|
|
441
|
+
```
|