前言
前端里接口参数拼接、搜索条件、富文本简单处理,几乎都绕不开字符串:拼 URL、拆 query、替换/截断文案。很多人习惯用 + 拼到眼花,或者到处 indexOf/substring,写多了难维护也容易出 bug。
用**模板字符串、split/join、正则**这三类能力,可以把「拼→ 拆 → 替换/匹配」写得更短、更稳。本文用 10 个左右常见场景,把日常该怎么选、为什么这么选、容易踩的坑讲清楚,只讲 80% 会用到的部分,不求覆盖所有正则语法。
适合读者:
- 会写 JS,但对模板字符串/正则什么时候用、怎么写有点模糊
- 刚学 JS,希望一开始就养成清晰的字符串写法
- 有经验的前端,想统一团队里的 URL 拼接、搜索条件、简单富文本处理
一、先搞清楚:模板字符串、split/join、正则分别在干什么
| 能力 | 在干什么 | 典型用法 |
|---|---|---|
| 模板字符串 | 用 ````` 和 ${} 把变量嵌进字符串,支持换行 |
拼 URL、拼文案、多行字符串 |
split |
按分隔符把字符串拆成数组 | 把 query 拆成键值对、按逗号/换行拆列表 |
join |
把数组用分隔符拼成字符串 | 把参数数组拼成 query、把标签数组拼成文案 |
| 正则 | 按模式匹配、替换、提取 | 替换占位符、校验格式、简单富文本处理 |
javascript
// 传统 + 拼接:多参数时很难看
const url = baseUrl + '/api/user?id=' + id + '&name=' + encodeURIComponent(name);
// 模板字符串:一眼看出「URL 长什么样」
const url = `${baseUrl}/api/user?id=${id}&name=${encodeURIComponent(name)}`;
记住一点:能一眼看出「最终长什么样」就用模板字符串;要「按规则拆开或拼起来」就用 split/join;要「按模式匹配或替换」就用正则。
二、模板字符串的常见用法
1. 接口 URL 与 query 拼接(模板字符串 + 一层编码)
应用场景
- 你要调一个列表接口(比如商品列表、用户列表),需要把「搜索关键词」「页码」「每页显示多少条」这些信息拼在接口地址后面,比如拼出
?keyword=张三&page=1&pageSize=10这种格式。
先搞懂一个核心问题:为啥不能直接拼?
- 就像咱们寄快递要写规范的地址(省 - 市 - 区 - 街道),URL(接口地址)也有自己的「书写规范」------ 有些字符(比如中文、空格、&、=)直接写进去,服务器会 "看不懂",甚至理解错意思。
举个最直白的例子
你要搜「用户 输入」(关键词里有空格),如果直接拼地址:/api/list?keyword=用户 输入&page=1
服务器会把「空格」当成 "参数分隔符",以为「keyword = 用户」是一个参数,「输入 & page=1」是另一个参数,直接解析错了!
javascript
const baseUrl = '/api/list'; // 接口基础地址
const params = {
keyword: '用户 输入', // 要搜索的关键词(有中文+空格,是"违规字符")
page: 1, // 第1页
pageSize: 10 // 每页显示10条
};
// ✅ 推荐写法:用 URLSearchParams 当"翻译官"(自动处理违规字符)
// 你可以把 URLSearchParams 理解成:专门处理URL参数的"小工具"
const query = new URLSearchParams({
keyword: params.keyword,
page: String(params.page), // 这个小工具只认字符串,数字要转一下
pageSize: String(params.pageSize),
}).toString(); // 把处理好的参数转成字符串
// 用模板字符串拼最终地址,结构一眼能看懂
const url = `${baseUrl}?${query}`;
console.log('自动处理后的地址:', url);
// 输出:/api/list?keyword=%E7%94%A8%E6%88%B7+%E8%BE%93%E5%85%A5&page=1&pageSize=10
// 你看:"用户 输入"被翻译成了 %E7%94%A8%E6%88%B7+%E8%BE%93%E5%85%A5,服务器能看懂了!
// ❌ 反面示例:直接拼(不翻译违规字符)------ 服务器看不懂
const badUrl1 = `${baseUrl}?keyword=${params.keyword}&page=${params.page}&pageSize=${params.pageSize}`;
console.log('直接拼的错误地址:', badUrl1);
// 输出:/api/list?keyword=用户 输入&page=1&pageSize=10(空格、中文没翻译,服务器解析错)
// ⚠️ 手动翻译写法(麻烦,容易漏):
// encodeURIComponent 就是"单个字符翻译器",只能翻译一个参数值
const encodedKeyword = encodeURIComponent(params.keyword); // 只翻译关键词
const encodedPage = encodeURIComponent(params.page); // 翻译页码
const encodedPageSize = encodeURIComponent(params.pageSize); // 翻译每页条数
const goodUrlByHand = `${baseUrl}?keyword=${encodedKeyword}&page=${encodedPage}&pageSize=${encodedPageSize}`;
console.log('手动翻译的正确地址:', goodUrlByHand);
// 输出和自动处理的一样,但要写3次 encodeURIComponent,参数多了容易漏!
更直观的表格说明
| 名词 | 小白版解释 | 什么时候用 |
|---|---|---|
encodeURIComponent |
单个 URL 参数的 "翻译器":把中文、空格这些服务器看不懂的字符,翻译成服务器能懂的 "编码"(比如把 "用户" 译成 % E7%94% A8% E6%88% B7) |
手动拼接 URL 参数时,给每个参数值单独翻译 |
URLSearchParams |
批量处理 URL 参数的 "智能翻译机":你把所有参数丢给它,它会自动调用 encodeURIComponent 给每个参数翻译,还能拼成规范的参数串 |
推荐优先用!不管参数多少,一次搞定,不翻车 |
关键注意点(小白必看)
- 只要参数里有
中文、空格、&、=这些字符,就必须 "翻译",否则接口会调失败 / 返回错误数据; URLSearchParams是 "懒人神器":不用记encodeURIComponent怎么写,不用怕漏翻译某个参数,丢进去就自动处理;- 小细节:
URLSearchParams只认字符串,所以数字类型的参数(比如page:1)要转成String (page),否则会报错。
2. 搜索条件:有值才带参数(过滤掉空值再拼)
场景: 只有 keyword 有值才带 keyword,只有 status 有值才带 status,避免 ?keyword=&status= 这种无意义参数。
javascript
const baseUrl = '/api/search';
const search = {
keyword: '张三', // 有实际值
status: '', // 空值(无意义)
type: '1', // 有实际值
};
// 第一步:筛选出非空的参数(去掉空字符串、全空格、null/undefined)
// Object.entries:把对象拆成[key, value]的数组,方便批量检查
// filter:筛选器,只留满足条件的参数
// trim():去掉字符串前后空格(比如用户只输空格也算空值)
const filtered = Object.fromEntries(
Object.entries(search).filter(([_, value]) => {
// 条件:值不是null/undefined,且去掉空格后不是空字符串
return value != null && String(value).trim() !== '';
})
);
// 第二步:用URLSearchParams自动编码参数,转成query字符串
const query = new URLSearchParams(filtered).toString();
// 第三步:拼接最终URL(有参数加?,没参数直接用基础地址)
const url = query ? `${baseUrl}?${query}` : baseUrl;
// 最终结果:/api/search?keyword=%E5%BC%A0%E4%B8%89&type=1
// 对比:如果没过滤,会是 /api/search?keyword=%E5%BC%A0%E4%B8%89&status=&type=1(多了无用的status=)
);
const query = new URLSearchParams(filtered).toString();
const url = query ? `${baseUrl}?${query}` : baseUrl;
// /api/search?keyword=%E5%BC%A0%E4%B8%89&type=1
核心名词小白解释:
| 代码片段 | 通俗理解 |
|---|---|
Object.entries(search) |
把{keyword:'张三', status:'', type:'1'}拆成[['keyword','张三'], ['status',''], ['type','1']],方便逐个检查值是否为空 |
Object.fromEntries(数组) |
把筛选后的数组(比如[['keyword','张三'], ['type','1']])还原成对象{keyword:'张三', type:'1'} |
value.trim() |
去掉字符串前后的空格,比如' 张三 '变'张三',' '变空字符串(避免 "只输空格" 被当成有效值) |
filter(...) |
只保留 "非空" 的参数,把status:''这种空值过滤掉 |
适用: 列表筛选项、搜索表单、任何「按条件带参」的接口。
3. 多行字符串、拼文案(模板字符串天然支持换行)
场景: 弹窗文案、邮件正文、多行提示。
javascript
const userName = '李四';
const count = 3;
const message = `尊敬的 ${userName}:
您有 ${count} 条待处理消息,请及时查看。`;
// 换行、变量都保留,不用 \n 和 + 拼
三、split / join 的常见用法
1. 把 URL 上的 search 拆成对象(split + 一次遍历)
场景: 从 ?id=1&name=test 得到 { id: '1', name: 'test' }。
javascript
const search = '?id=1&name=test';
// 推荐:直接用 URLSearchParams 解析(和上面「拼」对应)
const params = Object.fromEntries(new URLSearchParams(search));
// { id: '1', name: 'test' }
// 若不能用地道 API,再用 split
const params2 = search
.replace(/^\?/, '')
.split('&')
.reduce((acc, pair) => {
const [key, value] = pair.split('=');
acc[decodeURIComponent(key)] = decodeURIComponent(value ?? '');
return acc;
}, {});
注意: 值里可能带 =,所以「按第一个 = 拆」更稳,这里用 split('=') 只适合简单 value;复杂 query 建议统一用 URLSearchParams。
2. 把「逗号分隔的 id」拆成数组,再拼回去(split + join)
场景: 接口返回 ids: "1,2,3",要转成数组处理;提交时再拼成 "1,2,3"。
javascript
const idsStr = '1,2,3';
const ids = idsStr.split(',').map((id) => id.trim()).filter(Boolean);
// ['1', '2', '3']
// 提交时再拼回去
const idsStrAgain = ids.join(',');
// '1,2,3'
注意: split(',') 后习惯加 .map(s => s.trim()).filter(Boolean),避免空串和前后空格。
3. 按换行拆成数组(split('\n'))
场景: 用户输入多行标签、多行关键词,一行一个。
javascript
const input = ' tag1 \ntag2\n tag3 ';
const tags = input.split('\n').map((s) => s.trim()).filter(Boolean);
// ['tag1', 'tag2', 'tag3']
四、正则的 80% 用法(小白友好版:从基础到实战)
先搞懂:正则的 "基础积木"(小白版) 先记住这几个最常用的符号,就像搭积木一样,组合起来就能实现大部分匹配 / 替换需求:
| 符号 / 语法 | 小白版解释 | 举例子 |
|---|---|---|
/内容/ |
正则的 "容器",所有匹配规则都写在两个/之间 |
/abc/ 表示匹配字符串里的 abc |
/内容/g |
g = global(全局),表示匹配所有符合规则的内容,不是只匹配第一个 |
'aaa'.replace(/a/g, 'b') → bbb(不加 g 只替换第一个 a,变成 baa) |
\w |
匹配「字母、数字、下划线」(简单记:匹配 "单词字符") | /\w+/能匹配 name123、order_001 |
\d |
匹配「单个数字」(0-9) | /\d/匹配 5,/\d\d/ 匹配88 |
+ |
表示 "前面的规则至少出现 1 次" | /\d+/ 匹配 1 个或多个数字(比如 1、123) |
* |
表示 "前面的规则出现 0 次或多次"(用得少,优先记+) |
/\d*/ 能匹配空字符串、1、123 |
{n} |
表示 "前面的规则正好出现 n 次" | /\d{10}/匹配正好 10 个数字 |
^ |
匹配 "字符串的开头"(锚定开头) | /^1/只匹配以 1开头的字符串(比如 1380000 能匹配,a138 不能) |
$ |
匹配 "字符串的结尾"(锚定结尾) | /\d$/ 只匹配以数字结尾的字符串 |
[^>] |
[] 表示 "匹配其中任意一个字符",^ 在 [] 里表示 "排除" |
/[^>]+/匹配 "除了 > 之外的任意字符,至少 1 个" |
() |
捕获组:把匹配到的内容 "抓出来",后续能用到 | /\{(\w+)\}/ 里的 (\w+) 会把 {name} 里的 name 抓出来 |
有没有同学看不懂 /\{(\w+)\}/ 的?
看这里:
\是转义符:正则里想匹配{}/[]/()等特殊符号本身时,必须加\;/\{(\w+)\}/的核心是匹配{xxx}格式的字符串,其中:\{/\}匹配普通的{和};(\w+)抓出{}中间的字母/数字/下划线(比如 name);
- 新手写正则时,只要想匹配 "特殊符号本身",先加
\转义,就不会出错。
用法 1:占位符替换(把 {name} 换成真实值)
场景:服务端返回模板 " 您好,{name},您的订单{orderId}已发货 ",前端替换成当前用户和订单。 步骤拆解(小白能懂):
1. 规则/\{(\w+)\}/g 解析:
\{:匹配左大括号{(因为{是正则特殊符号,要加\转义,告诉正则 "这就是普通的{");(\w+):捕获组,匹配字母 / 数字 / 下划线(比如name、orderId),并把匹配结果存起来;\}:匹配右大括号};g:全局匹配,把所有{xxx}都找出来。
2. replace 回调函数:(_, key) => data[key] ?? ''
- 第一个参数
_:表示整个匹配的内容(比如{name}),用不到就用_占位; - 第二个参数
key:就是捕获组(\w+)抓到的内容(比如name); data[key] ?? '':从data里取对应的值,没有就用空串填充。
javascript
const template = '您好,{name},您的订单{orderId}已发货';
const data = { name: '王五', orderId: 'ORD001' };
// 核心代码
const result = template.replace(/\{(\w+)\}/g, (_, key) => data[key] ?? '');
console.log(result); // 输出:'您好,王五,您的订单ORD001已发货'
// 小白试错:如果不加g,只会替换第一个占位符
const badResult = template.replace(/\{(\w+)\}/, (_, key) => data[key] ?? '');
console.log(badResult); // 输出:'您好,王五,您的订单{orderId}已发货'
用法 2:富文本简单处理:去掉 HTML 标签只留纯文本
**场景:**列表摘要只展示纯文本,需要把 <p>xxx</p> 里的 xxx 拿出来,或去掉所有标签。 规则 /<[^>]+>/g 解析:
<:匹配左尖括号;[^>]+:匹配 "除了>之外的任意字符,至少 1 个"(比如p、strong、div class="title");>:匹配右尖括号;g:全局替换,把所有标签都去掉。
javascript
const html = '<p>这是一段<strong>加粗</strong>的文字 还有空格</p>';
// 第一步:去掉所有HTML标签
const textWithoutTag = html.replace(/<[^>]+>/g, '');
console.log(textWithoutTag); // 输出:'这是一段加粗的文字 还有空格'
// 第二步:还原常见的HTML实体(比如 换成空格)
const text = textWithoutTag
.replace(/ /g, ' ') // 空格实体转空格
.replace(/</g, '<') // < 实体转 <
.replace(/>/g, '>'); // > 实体转 >
console.log(text); // 输出:'这是一段加粗的文字 还有空格'
⚠️ 重要提醒 :这个规则只适合「简单、可控」的富文本(比如自己系统生成的短文本)。如果是复杂 HTML(比如带注释、<script>标签、属性里有>的),正则会失效,建议用 DOM 或专业库(如 cheerio)处理。
用法 3:富文本简单处理:限制摘要长度(截断 + 省略号)
场景 :列表里摘要最多显示 20 个字符,超出用 ...。 (先去标签再截断,避免截到标签中间,比如把<p>这是一段很长的文字</p>截成 <p>这是一段很长的文,导致标签不闭合)
javascript
// 封装成通用函数,小白直接用
const getSummary = (html, maxLen = 20) => {
// 第一步:先去标签和还原实体
const pureText = html
.replace(/<[^>]+>/g, '')
.replace(/ /g, ' ')
.replace(/</g, '<')
.replace(/>/g, '>');
// 第二步:判断长度,截断加省略号
if (pureText.length > maxLen) {
return pureText.slice(0, maxLen) + '...';
}
return pureText;
};
// 测试
const longHtml = '<div>这是一段非常非常长的富文本内容,需要截断显示</div>';
console.log(getSummary(longHtml, 10)); // 输出:'这是一段非常非常长...'
用法 4:简单格式校验(手机号、纯数字)
场景 :表单里「手机号」「纯数字」的简单校验,用 正则.test(要校验的字符串) ,返回 true/false。
1. 手机号校验
规则 /^1\d{10}$/ 解析:
^:字符串开头;1:第一个字符必须是 1(手机号开头都是 1);\d{10}:后面跟正好 10 个数字;$:字符串结尾; → 整体表示:整个字符串必须是 "1 + 10 个数字",长度正好 11 位。
javascript
// 封装手机号校验函数
const isPhoneValid = (phone) => {
// 先排除空值、非字符串情况
if (!phone || typeof phone !== 'string') return false;
return /^1\d{10}$/.test(phone);
};
// 测试
console.log(isPhoneValid('13800138000')); // true(正确手机号)
console.log(isPhoneValid('1380013800')); // false(只有10位)
console.log(isPhoneValid('12345678901')); // false(开头不是1)
console.log(isPhoneValid('1380013800a')); // false(包含字母)
2. 纯数字校验
规则 /^1\d{10}$/ 解析:
^:开头;\d+:至少 1 个数字;\d{10}:后面跟正好 10 个数字;$:结尾; → 整体表示:整个字符串只能是数字,不能有其他字符,且不能为空。
javascript
// 封装纯数字校验函数
const isPureNumber = (str) => {
if (!str) return false; // 空串返回false
return /^\d+$/.test(str);
};
// 测试
console.log(isPureNumber('12345')); // true
console.log(isPureNumber('123a5')); // false(含字母)
console.log(isPureNumber('')); // false(空串)
console.log(isPureNumber('0')); // true(单个0也符合)
用法总结
- 正则小白不用记所有语法,先掌握
/内容/g、\w/\d、+/{n}、^/$、()这几个核心符号,就能搞定大部分场景; - 正则的核心用法分 3 类:替换(
replace)、校验(test)、提取(match),其中替换和校验是日常用得最多的; - 写正则时,先拆解 "要匹配什么 / 排除什么",再用基础符号组合,优先加
g(全局)、^/``$`(整串匹配)避免漏匹配 / 错匹配; - 复杂 HTML 处理别用正则,优先用 DOM 或专业库,正则只适合简单片段。
五、容易踩的坑
1. 模板字符串里要算表达式,用 ${} 包起来
javascript
const a = 1, b = 2;
const wrong = `${a} + ${b} = a + b`; // '1 + 2 = a + b'
const right = `${a} + ${b} = ${a + b}`; // '1 + 2 = 3'
2. query 里的中文、空格、特殊字符必须编码
javascript
const name = '张 三';
const bad = `/api?name=${name}`; // 空格和中文会破坏 URL
const good = `/api?name=${encodeURIComponent(name)}`;
// 或统一用 URLSearchParams
3. split 不传参时按每个字符拆
javascript
'abc'.split(); // ['abc']
'abc'.split(''); // ['a','b','c']
要按「分隔符」拆就明确传参,例如 split(',')、split('\n')。
4. 空字符串 split 得到的是 ['']
javascript
''.split(','); // ['']
''.split(',').filter(Boolean); // []
拼 query、拼列表前若可能为空,先判断或 filter(Boolean),避免出现 ?key= 或末尾多余逗号。
5. 正则「去标签」不能覆盖所有 HTML 情况
javascript
// 像 <div class="a"> 这种可以匹配
// 但 <script>...</script>、注释、属性里的 > 等,正则容易出错
仅用于「自己能控制的、结构简单的」富文本片段;其它用 DOM 或专业库。
六、实战推荐写法模板
接口 GET 参数拼接(带空值过滤):
javascript
const baseUrl = '/api/list';
const params = { keyword: '...', page: 1, pageSize: 10, status: '' };
const query = new URLSearchParams(
Object.fromEntries(
Object.entries(params).filter(([_, v]) => v != null && String(v).trim() !== '')
)
).toString();
const url = query ? `${baseUrl}?${query}` : baseUrl;
从当前页 search 取参数:
javascript
const params = Object.fromEntries(new URLSearchParams(location.search));
const keyword = params.keyword ?? '';
逗号分隔字符串 ↔ 数组:
javascript
const toIds = (s) => (s ?? '').split(',').map((id) => id.trim()).filter(Boolean);
const toStr = (arr) => (arr ?? []).filter(Boolean).join(',');
简单占位符替换:
javascript
const fillTemplate = (template, data) =>
template.replace(/\{(\w+)\}/g, (_, key) => data[key] ?? '');
富文本摘要(去标签 + 截断):
javascript
const toSummary = (html, maxLen = 20) => {
const text = html.replace(/<[^>]+>/g, '').replace(/ /g, ' ');
return text.length > maxLen ? text.slice(0, maxLen) + '...' : text;
};
七、小结
| 场景 | 推荐写法 |
|---|---|
| 拼 URL、拼文案、多行字符串 | 模板字符串 ${base}?${query} |
| 拼/解析 query | URLSearchParams + 模板字符串 或 split/reduce |
| 有值才带参 | 先 filter 再 URLSearchParams,再拼到 URL |
| 逗号/换行拆成数组 | split(',') / split('\n') + trim + filter(Boolean) |
| 数组拼成字符串 | join(',') 等 |
占位符替换 {key} |
replace(/\{(\w+)\}/g, (_, key) => data[key]) |
| 简单去 HTML 标签 | replace(/<[^>]+>/g, '')(仅简单片段) |
| 摘要截断 | 先去标签再 slice(0, len) + '...' |
| 简单格式校验 | /^1\d{10}$/.test(phone) 等 |
记住:拼用模板字符串 + URLSearchParams,拆用 split/URLSearchParams,替换/匹配用正则。日常写接口参数、搜索条件、简单富文本时,先想清楚是「拼、拆、还是替换/校验」,再选对应方式,代码会清晰很多,也少踩编码和空值的坑。
特别提醒:
- query 里的中文和特殊字符一定要编码(
URLSearchParams或encodeURIComponent)。 - 空数组/空字符串在 split/join 时要考虑
filter(Boolean)和「是否带问号」。 - 正则只用于简单、可控的富文本;复杂 HTML 用 DOM 或专门库。
以上就是本次的学习分享,欢迎大家在评论区讨论指正,与大家共勉。
我是 Eugene,你的电子学友。
如果文章对你有帮助,别忘了点赞、收藏、加关注,你的认可是我持续输出的最大动力~