/**
* 说明:自定义的字符串原型方法(32)
* 注意:参数说明开头若已'(xxx)'开头表示默认值
* 其它:Object.insert()为自定义方法,与Object.assign()类似但不覆盖
* 其它:如果补充的属性不想被修改或删除,请调用Object.freeze()方法
*/
Object.insert(String.prototype, {
/**
* 将字符串按指定长度分割成数组
* @param {Number+} n (1)分割的字符长度:小于1时无效
* @param {Number} i (1)开始分割的索引
* @returns {Array|undefined}
*/
chunk: function (n, i) {
n = parseInt(n) || 1
if (n >= 1) {
i = parseInt(i) || 0
const j = this.length
const r = []
if (i < 0) i += j
for (i = Math.max(i, 0); i < j; i += n) r.push(this.substr(i, n))
return r
}
},
/**
* 首字母小写
* @returns {String}
*/
firstLower: function () {
return this.length !== 0 ? this[0].toLowerCase() + this.substr(1) : this + ''
},
/**
* 首字母大写
* @returns {String}
*/
firstUpper: function () {
return this.length !== 0 ? this[0].toUpperCase() + this.substr(1) : this + ''
},
/**
* 倒序不区分大小写查询
* @param {String} s 查询的字符串
* @param {Number} i (字符长度)最大查询的索引:负数则倒数
* @returns {Number}
*/
lastIndexNoCase: function (a, i) {
return this.slice(0, i).toUpperCase().lastIndexOf(a.toUpperCase())
},
/**
* 正则从后往前查找匹配到的首个文本(长匹配)
* 注意:原正则中如果有'.'可能会匹配到具有换行符的意外值
* @param {RegExp} reg 匹配的正则
* @returns {Array|null} 与*.match()返回的格式完全一致
*/
lastLongMatch: function (reg) {
reg = new RegExp(reg, 'g')
if (reg.test(this)) {
// 如果查找到,则获取结束位置
let i = reg.lastIndex
while (reg.test(this)) i = reg.lastIndex
// 获取最后的结束位置-1的字符串
let t = this.substring(--i), tem
// 重置结束索引并继续查找,直到匹配成功(短匹配)
reg.lastIndex = 0
while (!reg.test(t)) t = this[--i] + t
// 重置正则为起始匹配
reg = window.eval('/^(' + reg.source + ')/' + reg.flags.replace('g', ''))
// 因为刚才获取的字符串能被匹配,所以要在前补字符,进行长匹配
while (reg.test(tem = this[--i] + t)) t = tem
// 去除g模式后获取匹配数据
t = t.match(reg)
// 因为新正则补了括号,所以去除首项
t.shift()
// 修正数据
t.index = ++i
t.input = this + ''// 去除封装
return t
} else return null
},
/**
* 正则从后往前查找匹配到的首个文本(短匹配)
* 注意:原正则中如果有'.'可能会匹配到具有换行符的意外值
* @param {RegExp} reg 匹配的正则
* @returns {Array|null} 与*.match()返回的格式完全一致
*/
lastShortMatch: function (reg) {
reg = new RegExp(reg, 'g')
if (reg.test(str)) {
// 如果查找到,则获取结束位置
let i = reg.lastIndex
while (reg.test(str)) i = reg.lastIndex
// 获取最后的结束位置-1的字符串
let tem = str.substring(--i)
// 重置结束索引并继续查找,直到匹配成功(短匹配)
reg.lastIndex = 0
while (!reg.test(tem)) tem = str[--i] + tem
// 去除g模式后获取匹配数据
tem = tem.match(window.eval('/' + reg.source + '/' + reg.flags.replace('g', '')))
// 修正数据
tem.index = i
tem.input = str
return tem
} else return null
},
/**
* 判断字符串中有无URL的元字符
* @returns {true|undefined}
*/
hasUrlChar: function () {
if (this.match(/\s/)) return
else {
const chars = '"#*/:<>?\\|+'
let i = chars.length
while (i--) if (this.includes(chars[i])) return
return true
}
},
/**
* 模拟同名方法(版本兼容)
* @param {String} find 匹配的字符串
* @returns {Boolean}
*/
includes: function (find) {
return this.indexOf(find) !== -1
},
/**
* 正序不区分大小写查询
* @param {String} s 查询的字符串
* @param {Number} i (0)开始查询的索引:负数则倒数
* @returns {Number}
*/
indexNoCase: function (a, i) {
return this.toUpperCase().indexOf(a.toUpperCase(), i)
},
/**
* 模拟同名方法(版本兼容)
* 注意:必须使用低版写法
* @param {Number+} n (0)拼接的次数:若小于0则报错
* @returns {String}
*/
repeat: function (n) {
n = parseInt(n) || 0
if (n < 0) throw new Error('Invalid count value: ' + n)
// 利用指数思想拼接字符串
var t = (this), k = [1], v = [t], i = 2
for (; i < n; i <<= 1) k.push(i), v.push(t += t)
n -= i >> 1
i = k.length
// 补充剩余字符串
while (n > 0 && i--) {
if (n >= k[i]) n -= k[i], t += v[i]
// 没有也不影响结果,但在一定程度上减少内存溢出情况
k.pop()
v.pop()
}
return t
},
/**
* 替换对于文件名而言,不允许存在和可能导致异常的字符
* 常用于:设置文件名
* @param {String|Function} rep 替换的文本或方法:与*.replace()的第2个参数用法一致
* @param {Boolean} isOneByOne (假=多个一起替换)是否一对一替换
* @returns {String}
*/
replaceUrlChars: function (rep, isOneByOne) {
return this.replace(isOneByOne ? /["#%'\*\+\/:<>\?\\|]/g : /["#%'\*\+\/:<>\?\\|]+/g, rep)
},
/**
* 字符串逆序
* @returns {String}
*/
reverse: function () {
return this.split('').reverse().join('')
},
/**
* 模拟同名方法(低版兼容)
* 注意:必须使用低版写法
* 说明:已测试所有的特殊情况,返回结果均与内置方法一致
* @param {Number} i 开始截取的索引:负数则倒数
* @param {Number+} len (截取到最后)截取的长度:小于1均返回空字符串
* @returns {String}
*/
slice: function (i, end) {
var len = str.length
// 对起始索引强制取整
if (i = +i || 0) if (i < 0) {
i += len
if (i < 0) i = 0
} else if (i >= len) return ''
// 对结束索引强制取整
if (end === undefined) end = len
else if (end = +end || 0) {
if (end < 0) {
end += len
if (end < 1) return ''
} else if (end > len) end = len
} else return ''
// 截取
var s = ''
while (i < end) s += str[i++]
return s
},
/**
* 字符串排序
* @returns {String}
*/
sort: function () {
return this.split('').sort().join('')
},
/**
* 将字符串按照大写字母分离
* 说明:若多个大写字符连写,且不是字符串末尾的,则把最后一个字符与后面的文本拼接
* @returns {Array}
*/
splitByUpper: function () {
let a = this.match(/[A-Z]+/g)
if (!a) return [this.valueOf()]
let i = 0
, j = a.length - 1
, k
, m = this.indexOf(a[i])
, n
, r = m === 0 ? [] : [this.substring(0, m)]
for (; i < j; i++) {
k = a[i].length
n = this.indexOf(a[i + 1], m += k)
k === 1 ? r.push(this.substring(--m, n)) : r.push(a[i].substring(0, --k), this.substring(--m, n))
m = n
}
k = a[i].length - 1
// 获取字符串结尾
n = this.substring(m)
// 如果最后只有1个大写字符,或者就是字符串末尾,那么直接输出,否则分段输出
k === 0 || n === a[i] ? r.push(n) : r.push(a[i].substring(0, k), n.substring(k))
return r
},
/**
* 实现PHP中的strtr()的数组替换方法:逐字或逐键值对替换
* 注意:若两个参数都为字符串,则只会替换到的最短长度;已被替换的部分不会再次替换
* @param {String|Object} from 用于替换的字符串或对象
* @param {String} to (参数1为对象时无效)替换后的字符串
* @returns {String}
*/
strtr: function (from, to) {
if (typeof form === 'object' && form) {
const key = Object.keys(form)
const len = key.length
function r(s, i) {
return i === len ? s : s.split(key[i]).map(v => r(v, i + 1)).join(form[key[i]])
}
} else {
form += ''
to += ''
const len = Math.min(form.length, to.length)
function r(s, i) {
return i === len ? s : s.split(form[i]).map(v => r(v, i + 1)).join(to[i])
}
}
return r(this, 0)
},
/**
* 截取所有出现在俩字符串之间的文本
* @param {RegExp|String} a 前置正则(会去除g模式)或字符串:非正则会强制转为字符串
* @param {RegExp|String} b 后置正则(会去除g模式)或字符串:非正则会强制转为字符串
* @param {Number+} i (0)开始查找的索引,负数则倒数
* @returns {Array} 字符串数组
*/
subBothAll: function (a, b, i) {
// 重置字符串;获取模式类型
let str = this.slice(i), t = '', aa, bb
const r = []
if (Object.prototype.toString.call(a) === '[object RegExp]') {
t = 'r'
// 如果开启全局模式则去除
if (a.global) a = window.eval('/' + a.source + '/' + a.flags.replace('g', ''))
} else {
t = 's'
a += ''
}
if (Object.prototype.toString.call(b) === '[object RegExp]') {
t += 'r'
// 如果开启全局模式则去除
if (b.global) b = window.eval('/' + b.source + '/' + a.flags.replace('g', ''))
} else {
t += 's'
b += ''
}
// 截取数据
if (t === 'rr') {
while (true) {
t = str.match(a)
if (t) {
str = str.substring(t.index + t[0].length)
t = str.match(b)
if (t) {
r.push(str.substring(0, t.index))
str = str.substring(t.index + t[0].length)
} else break
} else break
}
} else if (t === 'rs') {
const bl = b.length
while (true) {
t = str.match(a)
if (t) {
t = str.indexOf(b, i = t.index + t[0].length)
if (t !== 1) {
r.push(str.substring(i, t))
str = str.substring(t + bl)
} else break
} else break
}
} else if (t === 'sr') {
i = 0
const al = a.length
while (true) {
t = str.indexOf(a, i)
if (t !== -1) {
str = str.substring(t + al)
t = str.match(b)
if (t) {
r.push(str.substring(0, t.index))
i = t.index + t[0].length
} else break
} else break
}
} else {
i = 0
const al = b.length
const bl = b.length
while (true) {
t = str.indexOf(a, i)
if (t !== -1) {
i = str.indexOf(b, t += al)
if (i !== -1) {
r.push(str.substring(t, i))
i += bl
} else break
} else break
}
}
return r
},
/**
* 截取首次出现在俩字符串之间的文本√
* @param {RegExp|String} a 前置正则(会去除g模式)或字符串:非正则会强制转为字符串
* @param {RegExp|String} b 后置正则(会去除g模式)或字符串:非正则会强制转为字符串
* @param {Number+} i (0)开始查找的索引,负数则倒数
* @returns {String|undefined} undefined=未找到
*/
subBothFirst: function (a, b, i) {
// 重置字符串/获取模式类型
let str = this.slice(i), t
if (Object.prototype.toString.call(a) === '[object RegExp]') {
t = 'r'
// 如果开启全局模式则去除
if (a.global) a = window.eval('/' + a.source + '/' + a.flags.replace('g', ''))
} else {
t = 's'
a += ''
}
if (Object.prototype.toString.call(b) === '[object RegExp]') {
t += 'r'
// 如果开启全局模式则去除
if (b.global) b = window.eval('/' + b.source + '/' + b.flags.replace('g', ''))
} else {
t += 's'
b += ''
}
// 截取数据
if (t === 'rr') {
t = str.match(a)
if (t) {
str = str.substring(t.index + t[0].length)
t = str.match(b)
if (t) return str.substring(0, t.index)
}
} else if (t === 'rs') {
t = str.match(a)
if (t) {
t = str.indexOf(b, i = t.index + t[0].length)
if (t !== 1) return str.substring(i, t)
}
} else if (t === 'sr') {
t = str.indexOf(a)
if (t !== -1) {
str = str.substring(t + a.length)
t = str.match(b)
if (t) return str.substring(0, t.index)
}
} else {
t = str.indexOf(a)
if (t !== -1) {
b = str.indexOf(b, t += a.length)
if (b !== -1) return str.substring(t, b)
}
}
return
},
/**
* 截取所有出现在俩字符串之间的文本√
* @param {RegExp|String} a 前置正则(会去除g模式)或字符串:非正则会强制转为字符串
* @param {RegExp|String} b 后置正则(会去除g模式)或字符串:非正则会强制转为字符串
* @param {Number+} i (字符长度)最大查找的索引,负数则倒数
* @returns {String|undefined} undefined=未找到
*/
subBothLast: function (a, b, i) {
// 重置字符串/获取模式类型
let str = this.slice(i), t
if (Object.prototype.toString.call(a) === '[object RegExp]') {
t = 'r'
// 如果开启全局模式则去除
if (a.global) a = window.eval('/' + a.source + '/' + a.flags.replace('g', ''))
} else {
t = 's'
a += ''
}
if (Object.prototype.toString.call(b) === '[object RegExp]') {
t += 'r'
// 如果开启全局模式则去除
if (b.global) b = window.eval('/' + b.source + '/' + b.flags.replace('g', ''))
} else {
t += 's'
b += ''
}
// 截取数据
if (t === 'rr') {
t = str.lastLongMatch(b)
if (t) {
str = str.substring(0, t.index)
t = str.lastShortMatch(a)
if (t) return str.substring(t.index + t[0].length)
}
} else if (t === 'rs') {
t = str.lastIndexOf(b)
if (t !== -1) {
str = str.substring(0, t)
t = str.lastShortMatch(a)
if (t) return str.substring(t.index + t[0].length)
}
} else if (t === 'sr') {
b = str.lastLongMatch(b)
if (b) {
t = str.lastIndexOf(a, b.index)
if (t !== -1) return str.substring(t + a.length, b.index)
}
} else {
b = str.lastIndexOf(b)
if (b !== -1) {
t = str.lastIndexOf(a, b)
if (t !== -1) return str.substring(t + a.length, b)
}
}
},
/**
* 截取出现在俩字符串之间的最长文本√
* @param {RegExp|String} a 前置正则(会去除g模式)或字符串:非正则会强制转为字符串
* @param {RegExp|String} b 后置正则(会去除g模式)或字符串:非正则会强制转为字符串
* @param {Number+} i (0)开始查找的索引,负数则倒数
* @returns {String}
*/
subBothLong: function (a, b, i) {
// 重置字符串/获取模式类型
let str = this.slice(i), t
if (Object.prototype.toString.call(a) === '[object RegExp]') {
t = 'r'
// 如果开启全局模式则去除
if (a.global) a = window.eval('/' + a.source + '/' + a.flags.replace('g', ''))
} else {
t = 's'
a += ''
}
if (Object.prototype.toString.call(b) === '[object RegExp]') {
t += 'r'
// 如果开启全局模式则去除
if (b.global) b = window.eval('/' + b.source + '/' + b.flags.replace('g', ''))
} else {
t += 's'
b += ''
}
// 截取数据
if (t === 'rr') {
t = str.match(a)
if (t) {
str = str.substring(t.index + t[0].length)
if (t = str.lastLongMatch(b)) return str.substring(0, t.index)
}
} else if (t === 'rs') {
t = str.lastIndexOf(b)
if (t !== -1) {
str = str.substring(0, t)
t = str.match(a)
if (t) return str.substring(t.index + t[0].length)
}
} else if (t === 'sr') {
t = str.indexOf(a)
if (t !== -1) {
str = str.substring(t + a.length)
if (t = str.lastLongMatch(b)) return str.substring(0, t.index)
}
} else {
t = str.indexOf(a)
if (t !== -1) {
str = str.substring(t + a.length)
t = str.lastIndexOf(b)
if (t !== -1) return str.substring(0, t)
}
}
},
/**
* 截取字符串首次出现之后的文本√
* @param {RegExp|String} match 查找的正则(会去除g模式)或文本:非正则会强制转为字符串
* @param {Number+} i (0)结束截取的索引:负数则倒数
* @returns {String|null} null=未找到
*/
subFirstAfter: function (match, i) {
// 重置字符串;获取模式类型
const str = this.slice(0, i)
if (Object.prototype.toString.call(match) === '[object RegExp]') {
// 如果开启全局模式则去除
if (match.global) match = window.eval('/' + match.source + '/' + match.flags.replace('g', ''))
i = str.match(match)
return i ? str.substring(i.index + i[0].length) : null
} else {
i = str.indexOf(match += '')
return i === -1 ? null : str.substring(i + match.length)
}
},
/**
* 截取字符串首次出现之前的文本√
* @param {RegExp|String} match 查找的正则(会去除g模式)或文本:非正则会强制转为字符串
* @param {Number+} i (0)开始截取的索引:负数则倒数
* @returns {String|null} null=未找到
*/
subFirstBefore: function (match, i) {
// 重置字符串;获取模式类型
const str = this.slice(i)
if (Object.prototype.toString.call(match) === '[object RegExp]') {
// 如果开启全局模式则去除
if (match.global) match = window.eval('/' + match.source + '/' + match.flags.replace('g', ''))
i = str.match(match)
return i ? str.substring(0, i.index) : null
} else {
i = str.indexOf(match + '')
return i === -1 ? null : str.substring(0, i)
}
},
/**
* 截取字符串出现第n次之后的文本√
* @param {RegExp|String} match 查找的正则(会去除g模式)或文本:非正则会强制转为字符串
* @param {Number+} n (1)查找第几个匹配到的文本:非数字或负数均为1
* @param {Number+} i (0)开始截取的索引:负数则倒数
* @returns {String|null} null=未找到
*/
subIndexAfter: function (match, n, i) {
// 对n强制取整
n = +n || parseFloat(n) || 1
n = Math.min(Math.max(n, 1), this.length)
// 重置字符串;获取模式类型
let str = this.slice(i)
if (Object.prototype.toString.call(match) === '[object RegExp]') {
// 如果开启全局模式则去除
if (match.global) match = window.eval('/' + match.source + '/' + match.flags.replace('g', ''))
// 匹配到指定次数
for (; n !== 0 && (i = str.match(match)); n--) str = str.substring(i.index + i[0].length)
return i ? str : null
} else {
match += ''
const ml = match.length
// 匹配到指定次数
i = str.indexOf(match)
for (n--; n > 0 && i !== -1; n--) i = str.indexOf(match, i + ml)
return i === -1 ? null : str.substring(i + ml)
}
},
/**
* 截取字符串出现第n次之前的文本√
* @param {RegExp|String} match 查找的正则(会去除g模式)或文本:非正则会强制转为字符串
* @param {Number+} n (1)查找第几个匹配到的文本:非数字或负数均为1
* @param {Number+} i (0)开始截取的索引:负数则倒数
* @returns {String|null} null=未找到
*/
subIndexBefore: function (match, n, i) {
// 对n强制取整
n = +n || parseFloat(n) || 1
n = Math.min(Math.max(n, 1), this.length)
// 重置字符串;获取模式类型
let str = this.slice(i)
if (Object.prototype.toString.call(match) === '[object RegExp]') {
// 如果开启全局模式则去除
if (match.global) match = window.eval('/' + match.source + '/' + match.flags.replace('g', ''))
// 匹配到指定次数
let tem = str
for (; n !== 0 && (i = tem.match(match)); n--) tem = tem.substring(i.index + i[0].length)
return i ? str.substring(0, str.length - tem.length - i[0].length) : null
} else {
match += ''
const ml = match.length
// 匹配到指定次数
i = str.indexOf(match)
for (n--; n > 0 && i !== -1; n--) i = str.indexOf(match, i + ml)
return i === -1 ? null : str.substring(0, i)
}
},
/**
* 截取字符串最后出现之后的文本√
* @param {RegExp|String} match 查找的正则(会去除g模式)或文本:非正则会强制转为字符串
* @param {Number+} i (字符长度)结束截取的索引:负数则倒数
* @returns {String|null} null=未找到
*/
subLastAfter: function (match, i) {
// 重置字符串;获取模式类型
const str = this.slice(0, i)
if (Object.prototype.toString.call(match) === '[object RegExp]') {
// 如果开启全局模式则去除
if (match.global) match = window.eval('/' + match.source + '/' + match.flags.replace('g', ''))
i = str.lastShortMatch(match)
return i ? str.substring(i.index + i[0].length) : null
} else {
i = str.lastIndexOf(match += '')
return i === -1 ? null : str.substring(i + match.length)
}
},
/**
* 截取字符串最后出现之前的文本√
* @param {RegExp|String} match 查找的正则(会去除g模式)或文本:非正则会强制转为字符串
* @param {Number+} i (字符长度)结束截取的索引:负数则倒数
* @returns {String|null} null=未找到
*/
subLastBefore: function (match, i) {
// 重置字符串;获取模式类型
const str = this.slice(0, i)
if (Object.prototype.toString.call(match) === '[object RegExp]') {
// 如果开启全局模式则去除
if (match.global) match = window.eval('/' + match.source + '/' + match.flags.replace('g', ''))
i = str.lastLongMatch(match)
return i ? str.substring(0, i.index) : null
} else {
i = str.lastIndexOf(match + '')
return i === -1 ? null : str.substring(0, i)
}
},
/**
* 模拟同名方法(防止失效)
* 注意:必须使用低版写法
* 说明:已测试所有的特殊情况,返回结果均与内置方法一致
* @param {Number} i 开始截取的索引:负数则倒数
* @param {Number+} len (截取到最后)截取的长度:小于1均返回空字符串
* @returns {String}
*/
substr: function (i, len) {
const max = str.length
// 对起始索引强制取整
if (i = +i || 0) if (i < 0) {
i += max
if (i < 0) i = 0
} else if (i >= max) return ''
// 对结束索引强制取整
if (len === undefined) len = max
else if (len = +len) {
if (len < 1) return ''
else if (len < max) len = Math.min(len + i, max)
else len = max
} else return ''
// 截取
let s = ''
while (i < len) s += str[i++]
return s
},
/**
* 模拟同名方法(低版本兼容)
* 注意:必须使用低版写法
* 说明:已测试所有的特殊情况,返回结果均与内置方法一致
* @param {Number} i 开始截取的索引:小于1均为0
* @param {Number+} end (undefined=截取到最后)最后截取的索引
* @returns {String}
*/
substring: function (i, end) {
let max = str.length
// 对起始索引强制取整
if (i = +i || 0) {
if (i < 0) i = 0
else if (i > max) i = max
}
// 对结束索引强制取整
if (end === undefined) end = max
else {
end = +end || 0
if (end < 0) end = 0
else if (end > max) end = max
}
// 截取
let s = ''
if (i < end) while (i < end) s += str[i++]
else while (end < i) s += str[end++]
return s
},
/**
* 把HTML文本解析为正常文本
* @param {String} lineBreak ('\r\n')换行符:非'\r'或'\n'均为默认值
* @returns {String}
*/
toHTML: function (lineBreak) {
// 用于转化HTML和字符实体
const e = document.createElement('span')
// 转化HTML、字符实体、换行符
return this.replace(/&(#\d|\w)+;/g, v => {
e.innerHTML = v
return e.textContent
}).replace(/\n|\r/g, lineBreak === '\r' || lineBreak === '\n' ? lineBreak : '\r\n')
},
/**
* 把字符串按照GET请求解析,并支持多选:多选格式=[{k:二维键名,v:数据},...]
* 说明:需兼容低版写法
* @param {String} prefix (undefined='')每个键名要拼接的前缀:防止与原型冲突
* @returns {Object}
*/
toGET: function (prefix) {
// 把参数强制转为字符串
prefix = prefix === undefined ? '' : prefix + ''
var r = {}
// 获取请求数据,但因键名中可能存在'&',所以此时还不能转码
, a = location.search.substring(1).split('&')
, i = 0, j = a.length, k, v
for (; i < j; i++) {
k = a[i].indexOf('=')
// 转码
if (k === -1) {
v = ''
k = decodeURIComponent(a[i])
} else {
v = decodeURIComponent(a[i].substring(k + 1))
k = decodeURIComponent(a[i].substring(0, k))
}
// 多选判断
var k1 = k.indexOf('['), k2 = k1 === -1 ? -1 : k.indexOf(']', k1 + 1)
if (k2 === -1) r[prefix + k] = v
else {// 是多选时
k = prefix + k.substring(0, k1)// 1维键名
// 添加到对象数组中
if (typeof r[k] !== 'object') r[k] = []
r[k].push({ k: k.substring(k1 + 1, k2), v: v })
}
}
return r
},
/**
* 把字符串转为正则:主要处理正则的元字符
* @param {String} model (无模式)转化后正则的模式:是字符串时会强制转为小写字符串
* @param {Boolean|String} toMetaChars (假=不转化)Boolean=是否转化所有字符;String=要转化的元字符(非字符串会被强制转化)
* @returns {RegExp|false} false=转化失败
*/
toRegExp: function (model, toMetaChars) {
let str = this
// 转化正则模式
model = typeof model === 'string' ? model.toLowerCase() : ''
// 如果要转化元字符
if (toMetaChars) {
const metaChars = '\\$()*+-./?[]^{}' // 必须以"\\"开头,且无重复字符
const ml = metaChars.length
let i = 0
// 为true则全部转义,否则仅转义参数中存在的
if (toMetaChars === true)
for (; i < ml; i++) str = str.split(metaChars[i]).join('\\' + metaChars[i])
else
for (toMetaChars += ''; i < ml; i++) if (toMetaChars.includes(metaChars[i])) str = str.split(metaChars[i]).join('\\' + metaChars[i])
}
try {
return new RegExp(str, model)
} catch (e) {
throw new Error(e)
}
},
/**
* 字符串去重
* @returns {String}
*/
unique: function () {
let a = this, r = ''
while (a) {
r += a[0]
a = a.split(a[0]).join('')
}
return r
},
})
Object.freeze(String.prototype)
JS:自定义String实例方法(按长度/大写字母分离,去重,排序,逆序,转为HTML/GET/正则,双向截取,从后往前正则匹配,1对1替换=PHP中的strtr(),部分新/旧版的原型方法...)
于 2024-07-25 12:14:55 首次发布