JS不再百度系列-字符串的基本操作
这篇记录的是我常用的字符串操作。本文全部内容来自MDN。完整的可以看这个
注意:
- 所有的字符串方法均不会修改原字符串
String.prototype和Array.prototype中都有的方法
concat
返回值:新的拼接好的字符串
eg:
a = "a"
a.concat([1,2]) //"a1,2"
a.concat(1,true,null, undefined) //a1truenullundefined,各元素会先用String()处理转化成字符串
includes
语法:
str.includes(searchString[, position])
- searchString:要在此字符串中搜索的字符串(可以是字符串,不一定是单个字符。indexOf和lastIndexOf同),如果不是字符串,会先用String()转为字符串,这点和Array中的includes的表现不一样
- position:可选,默认值为0。指定从当前字符串的哪个索引位置开始搜寻子字符串。不支持负数,若是指定为负数,等同于指定为0
eg:
a = ["1", "2", "3"]
a.includes(1) //false
b = "123"
b.includes(1) //true
a.includes("2", -1) //false
a.includes("2", -2) //true
b.includes("2", -1) //true
b.includes("2", -2) //true
b.includes("2", 1) //true
b.includes("2", 2) //false
indexOf
语法:
str.indexOf(searchValue[, fromIndex])
用法基本和数组中的indexOf一样,支持两个参数。
第二个参数可选,默认值为0,不支持负数,或者说当第二个参数是负数时,表现会比较复杂。但我个人认为这没有记忆的必要
如果 fromIndex < 0
则查找整个字符串(如同传进了 0)。如果 fromIndex >= str.length
,则该方法返回 -1。当被查找的字符串是一个空字符串,fromIndex <= 0
时返回0
,0 < fromIndex <= str.length
时返回fromIndex
,fromIndex > str.length
时返回str.length
。
eg:
a = "asd";
//当被查找的字符串是一个空字符串
a.indexOf("", -1); //0 fromIndex <= 0时返回0
a.indexOf("", 1); //1 0 < fromIndex <= str.elngth时返回fromIndex
a.indexOf("", 9); //3 fromIdex > str.length时返回str.length
lastIndexOf
语法:
str.lastIndexOf(searchValue[, fromIndex])
第二个参数可选,默认值为str.length,不支持负数。如果为负值,则被看作 0。如果fromIndex > str.length
,则 fromIndex
被看作 str.length
总结:
- 如果被查找的是一个空字符串,行为会比较特别
- 个人觉得,使用String.prototype.includes/indexOf/lastIndexOf时,如果需要指定第二个参数,记得用正数表示就好,没必要使用负数,得不偿失
slice
语法:
str.slice(beginSlice[, endSlice])
参数:
- beginSlice
sourceLength + beginSlice
看待,这里的sourceLength 是字符串的长度
(例如, 如果beginSlice
是 -3 则看作是: sourceLength - 3
)。sourceLength + beginSlice为值指定为负数时的计算原理- endSlice
slice
会一直提取到字符串末尾。如果该参数为负数,则被看作是 sourceLength + endSlice返回值:
一个从原字符串中提取出来的新字符串
字符相关操作
charAt
定义:从一个字符串中返回指定位置的字符
返回值:一个字符
语法:
str.charAt(index = 0)
参数:
- index:一个介于0 和字符串长度减1之间的整数。 (0~length-1),默认为0。如果超过length-1,返回空字符;
charCodeAt
定义:方法返回0到65535之间的整数,表示给定索引处的UTF-16代码单元 (在 Unicode 编码单元表示一个单一的 UTF-16 编码单元的情况下,UTF-16 编码单元匹配 Unicode 编码单元。但在——例如 Unicode 编码单元 > 0x10000 的这种——不能被一个 UTF-16 编码单元单独表示的情况下,只能匹配 Unicode 代理对的第一个编码单元)
以我的理解,UTF-16编码方式固定以两个字节表示一个字符,两个字节即上文说的UTF-16编码单元。charCodeAt返回表示指定字符UTF-16编码单元的整数。但总有超出两个字节表示的字符,譬如有些字符需要四个字节表示,这时charCodeAt就返回第一个编码单元,即四个字节中的前两个字节
具体建议阅读阮一峰老师的:ES6入门
语法:
str.charCodeAt(index)
参数:
index,
一个大于等于 0,小于字符串长度的整数。如果不是一个数值,则默认为 0
返回值:表示给定索引处(String中index索引处)字符的 UTF-16 代码单元值的数字(Number);如果索引超出范围,则返回 NaN
codePointAt
定义:方法返回 一个 Unicode 编码点值的非负整数(可以识别大于双字节存储的字符)
返回值:表示Unicode编码点值的非负整数
截取操作
slice
参考上面
substr
先搬一下来自MDN的警告
警告: 尽管 String.prototype.substr(…)
没有严格被废弃 (as in "removed from the Web standards"), 但它被认作是遗留的函数并且可以的话应该避免使用。它并非JavaScript核心语言的一部分,未来将可能会被移除掉。如果可以的话,使用 substring()
替代它.
鉴于此,直接跳过至substring
substring
定义:返回一个字符串在开始索引到结束索引之间的一个子集(新的字符串,包括开始索引不包括结束索引), 或从开始索引直到字符串的末尾(若省略第二个参数)的一个子集
返回值:包含给定字符串的指定部分的新字符串
语法:
str.substring(indexStart[, indexEnd])
参数
- indexStart。需要截取的第一个字符的索引,该字符作为返回的字符串的首字母。
- indexEnd。可选。一个 0 到字符串长度之间的整数(不支持负数,若是负数,返回原字符串),默认是str.length。以该数字为索引的字符不包含在截取的字符串内。若是substr,该参数指定了要截取字符数
str = "asd"
str.substring(-5) //asd
支持正则的方法
match 检索字符串
定义:检索返回一个字符串匹配正则表达式的的结果
返回值:
语法:str.match(regexp)
参数:
- regexp
new RegExp(obj)
将其转换为一个 RegExp
。如果你没有给出任何参数并直接使用match() 方法 ,你将会得到一 个包含空字符串的 Array
:[""] 。返回值:
Array
),但不会返回捕获组,或者未匹配返回 null
。Array
)( 关联数组 )。 在这种情况下,返回的项目将具有如下所述的附加属性,或者未匹配返回 null
。附加属性
如上所述,匹配的结果包含如下所述的附加特性。
groups
: 一个捕获组数组 或undefined
(如果没有定义命名捕获组)。index
: 匹配的结果的开始位置input
: 搜索的字符串.
eg:
a = "12311";
a.match(/1/g); //["1", "1", "1"],不会返回捕获组
a.match(/8/g);
a.match(/1/); //["1", index: 0, input: "12311", groups: undefined]
a.match(/8/); //null
总结一下返回值有三种情况:
- null,未匹配到
- 该字符串所有匹配正则表达式的结果组成的数组,可通过其得知字符串有多个个能匹配正则的子串,正则表达式有g标志的情况下
- 具有附加属性的捕获组(一个关联数组)
search 检索字符串
定义:执行正则表达式和 String
对象之间的一个搜索匹配
语法:str.search(regexp)
参数:
- regexp
返回值:如果匹配成功,则 search()
返回正则表达式在字符串中首次匹配项的索引;否则,返回 -1
感觉像是支持正则的indexOf,不阐述更多
replace 替换
这个应用场景比较多
定义:将字符串中第一个或全部匹配指定字符串或正则的字符串替换成指定的值或是指定函数调用后的返回值
返回值:替换后的字符串
语法:str.replace(regexp|substr, newSubStr|function)
可以接收两个参数,且两个参数都有两种模式
参数
- 第一个参数如果指定是字符串,则只有字符串中的第一个匹配项会被替换;如果是一个正则表达式,则可以通过g标志替换所有匹配项目
- 第二个参数的两种模式(字符串和函数)
? | 插入一个 "$"。 |
$& | 插入匹配的子串。 |
$` | 插入当前匹配的子串左边的内容。 |
$' | 插入当前匹配的子串右边的内容。 |
$n | 假如第一个参数是 |
function
(replacement)一个用来创建新子字符串的函数,该函数的返回值将替换掉第一个参数匹配到的结果。参考下面的指定一个函数作为参数
match | 匹配的子串。(对应于上述的$&。) |
p1,p2, ... | 假如replace()方法的第一个参数是一个 |
offset | 匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是 |
string | 被匹配的原字符串。 |
eg:
a = "1a2s3d4f"
a.replace(/(\d{1})(\w{1})/, "?, $&, $`, $', $1, $2")
输出:
//$, 1a, , 2s3d4f, 1, a2s3d4f 空格会保存,会保留格式
a.replace(/(\d{1})(\w{1})/g, function(match, p1, p2, offest, str){
console.log(match, p1, p2, offest, str)
})
输出:
1a 1 a 0 1a2s3d4f
2s 2 s 2 1a2s3d4f
3d 3 d 4 1a2s3d4f
4f 4 f 6 1a2s3d4f
格式化字符串,将形如"yyyymmdd"格式的日期字符串转化为"yyyy年mm月dd日"
str = "20190509";
我之前会这么写:str.substring(0,4)+'年'+str.substring(4,6)+'月'+str.substring(6,8)+'日';没错就是这么直男
现在我会换种写法:str.replace(/(\d{4})(\d{2})(\d{2})/, "$1年$2月$3日");看上去好一点
split
split竟然支持正则,我之前以为它只支持字符串,惭愧。
定义:使用指定的分隔符字符串将一个String
对象分割成字符串数组,以将字符串分隔为子字符串,以确定每个拆分的位置
返回值:分割后的字符串数组
语法:str.split([separator[, limit]])
参数:
- separator
separator
可以是一个字符串或正则表达式。 如果纯文本分隔符包含多个字符,则必须找到整个字符串来表示分割点。如果在str中省略或不出现分隔符,则返回的数组包含一个由整个字符串组成的元素。如果分隔符为空字符串,则将str原字符串中每个字符的数组形式返回。- limit
eg:
a = "a1b2c3d4";
//如果在str中省略或不出现分隔符,则返回的数组包含一个由整个字符串组成的元素
a.split() //["a1b2c3d4"]
a.split(7) //["a1b2c3d4"]
//如果分隔符为空字符串,则将str原字符串中每个字符的数组形式返回。
a.split("") //["a", "1", "b", "2", "c", "3", "d", "4"]
//limit
a.split(/\d{1}/) //["a", "b", "c", "d", ""]
a.split(/\d{1}/, 3) //取上面数组的前三位 ["a", "b", "c"]
//如果分隔符能匹配到字符串最后一位,则数组最后一位是一个空字符串
a.split(/\d{1}/) //["a", "b", "c", "d", ""]
b = "1a2a3a4a"
b.split("a") //["1", "2", "3", "4", ""]
总结:
- 在字符串支持正则的方法中,match和search都是只支持正则。如果传入一个非正则表达式对象
obj
,则会使用new RegExp(obj)
隐式地将其转换为正则表达式对象 - replace如果第一个参数是字符串,则只有字符串中的第一个匹配项会被替换
其他
toLowerCase转小写
toUpperCase转大写
trim去掉字符串左右两端的空格
trimRight去掉字符串右端空格
trimLeft去掉字符串左端空格
转载自:https://juejin.cn/post/6844903833219366925