批量清除隐藏字符
从 ERP 系统导出的 3000 条客户姓名,在 Excel 里看起来正常,但导入 CRM 时总有 40 条报错。排查发现是末尾附带了不可见的换行符和制表符。用本工具的正则替换模式,输入 `[\r\n\t]+` 替换为空,3 秒清掉所有隐藏字符,数据直接通过校验,不用逐行用 LEN 函数定位脏数据。
\d 数字 \w 词字符 \s 空白 . 任意 ^$ 行首尾
\b 词边界 (…) 捕获组 + * ? 量词 · 替换用 $1 引用| 启用 | 查找 | 替换为 |
|---|
查找=替换(首个等号为分隔,替换可空)写 SQL 或改代码时,要把一串手机号里的空格、横杠、括号全去掉,手动替换一个字段还行,一百个就手酸了。这个工具在浏览器里做三种替换:普通替换删固定字符、正则替换按模式匹配、批量规则允许把多个替换条件存成一套方案。正则替换支持捕获组和反向引用,能处理“把 010-12345678 转成 (010)12345678”这类带结构的转换。所有文本只留在浏览器内存里,不离开设备。
从 ERP 系统导出的 3000 条客户姓名,在 Excel 里看起来正常,但导入 CRM 时总有 40 条报错。排查发现是末尾附带了不可见的换行符和制表符。用本工具的正则替换模式,输入 `[\r\n\t]+` 替换为空,3 秒清掉所有隐藏字符,数据直接通过校验,不用逐行用 LEN 函数定位脏数据。
三个供应商发来的 SKU 编码格式各异:A 厂用 `ABC-123`、B 厂用 `abc_123`、C 厂用 `ABC123`。采购部需要统一为 `ABC-00123`(字母大写、连字符、5 位数字补零)。用本工具的批量规则功能,建三条规则依次执行:转大写、连字符替换下划线、数字补零。2000 条编码一次处理完,不再人工肉眼校对。
从语雀复制了一篇 5000 字的文章到公众号后台,粘贴后自带大量行内样式(字体、字号、颜色标签)。手动清除至少 20 分钟。用本工具的正则替换,输入 `<[^>]+>` 匹配所有 HTML 标签并替换为空,保留纯文本。再把连续两个以上的换行符 `\n{2,}` 替换为单个 `\n`,文章恢复干净段落结构,直接套用公众号的模板样式。
线上故障需要把 200MB 的 Nginx 日志发给外包团队排查,但日志里混着用户手机号(11 位连续数字)和 IP 地址。用本工具的正则替换,手机号用 `1[3-9]\d{9}` 匹配并替换为 `138****0000`,IP 用 `\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}` 替换为 `x.x.x.x`。两条规则跑完,日志脱敏后直接打包发走,不经过任何云服务,数据不出本地浏览器。
法务审完一份 15 页的合同,删了第 3 条和第 7 条,插入了两条新条款。原来的「第 1 条、第 2 条……」序号全乱。用本工具的正则替换,先匹配所有 `第\d+条` 替换为占位符 `§§§`,然后手动按顺序替换回去(第一次替换为 `第1条`,第二次替换为 `第2条`……)。10 分钟完成序号重排,避免 Word 自动编号在跨平台时乱序的问题。
| 维度 | 本工具 | 在线替换站 | 手工/编辑器替换 |
|---|---|---|---|
| 替换方式 | 普通/正则/批量规则三合一 | 多数仅支持普通替换或正则二选一 | 需手动逐条执行,无批量规则 |
| 批量规则 | 支持预设多条规则一次执行 | 少数支持,但常限免费版条数 | 无此功能,需重复操作 |
| 正则支持 | 完整正则语法,无阉割 | 部分站点阉割捕获组/回溯 | 依赖编辑器,需自行安装插件 |
| 隐私 | 纯浏览器处理,文件不上传 | 需上传文本至服务器 | 本地处理,但无辅助功能 |
| 速度 | 即时替换,无网络延迟 | 取决于上传+服务器响应 | 取决于手动操作速度 |
| 离线可用 | 完全离线,无网络也可用 | 依赖网络,断网不可用 | 完全离线 |
| 大小限制 | 无限制(浏览器内存上限) | 常有字符数/文件大小限制 | 取决于编辑器自身限制 |
| 输入 | 输出 | 说明 |
|---|---|---|
| 原文本:"hello world" 查找:"world" 替换为:"everyone" | hello everyone | 常规:最简单的普通文本替换,验证基本查找替换功能是否正常 |
| 原文本:"abc123abc" 查找:"abc" 替换为:"XYZ" | XYZ123XYZ | 常规:替换所有匹配项(全局替换),验证是否只替换第一个还是全部 |
| 原文本:"价格是100元,折扣后80元" 查找:"\\d+" 替换为:"[数字]" 启用正则 | 价格是[数字]元,折扣后[数字]元 | 边界:正则替换数字,验证正则引擎是否支持 \d+ 匹配所有数字 |
| 原文本:"test@example.com" 查找:"^test" 替换为:"demo" 启用正则 | demo@example.com | 边界:正则行首锚点 ^ 的匹配,验证正则模式是否从开头匹配 |
| 原文本:""(空字符串) 查找:"a" 替换为:"b" | (空字符串) | 边界:空输入的处理,验证工具不会报错或输出异常字符 |
| 原文本:"Hello\nWorld" 查找:"\n" 替换为:" " | Hello World | 易错:换行符替换,用户常误以为直接输入回车即可,实际需用 \n 转义 |
| 原文本:"a.b.c" 查找:"." 替换为:"-" 不启用正则 | a.b.c | 易错:普通模式下点号 . 是字面字符,不匹配任意字符;若用户期望正则行为需开启正则模式 |
1.正则替换时忘记转义替换字符串中的 $ 和 \
将 (\d+) 替换为 编号$1,但替换内容写成 "编号$1"在替换字符串中写 "编号\$1" 或使用替换函数时对 $ 进行转义在大多数正则引擎中,替换字符串里的 $1 是反向引用,而字面 $ 必须写成 $$ 或 \$,否则会报错或替换为空白。
2.批量规则中多条规则互相覆盖,顺序错误
先替换 a→b,再替换 b→c,结果所有 a 都变成了 c如果目标是 a→b 且 b→c 分别处理,应使用单次替换或调整规则顺序为 b→c 在前、a→b 在后批量替换是顺序执行的,后一条规则会作用于前一条的结果。若规则间有重叠,顺序决定最终输出,需按依赖关系排列。
3.普通替换时大小写不敏感但未启用标志
想将 "Hello" 替换为 "Hi",但输入 "hello" 未被替换启用大小写不敏感选项(如 /i 标志)或手动匹配 "[Hh]ello"普通替换默认区分大小写。若需忽略大小写,必须显式设置标志或使用正则表达式。
4.正则替换中使用捕获组但未正确引用组号
用 (\w+)@(\w+) 匹配邮箱,替换为 "$2@$1" 但结果变成 "$2@$1" 字面在替换字符串中写 "$2@$1" 时,确保替换引擎支持反向引用语法(通常为 $1、\1 或 ${1})不同工具/语言对反向引用的语法不同:JavaScript 用 $1,Python 用 \1,部分工具用 ${1}。使用前需确认当前环境支持的格式。
5.批量规则中混用普通替换和正则替换导致意外行为
一条规则设为普通替换 "a.b",另一条为正则替换 "a.b",结果第一条只匹配字面 "a.b",第二条匹配 "axb"统一规则类型,或明确每条规则的类型标志(普通/正则),避免混用普通替换对特殊字符无转义,正则替换中 . 是元字符。混用时容易混淆预期行为,建议同一批规则保持类型一致。
6.替换空字符串导致死循环或无限替换
将 "" 替换为 "x",结果每个字符间都插入 x,文本无限增长避免替换空字符串;若需插入字符,应指定具体位置(如用正则 ^ 或 $)替换空字符串会匹配所有零宽位置(字符之间、开头、结尾),导致每次替换后新插入的字符又产生新的空位,形成无限循环。
7.正则替换时误用贪婪匹配导致替换范围过大
想将 <b>text</b> 加粗,用正则 <b>.*</b> 替换为 <strong>$1</strong>使用非贪婪匹配 <b>.*?</b> 或更精确的 <b>[^<]*</b>贪婪 .* 会匹配到最后一个 </b>,导致 <b>a</b>...<b>b</b> 被整体替换。非贪婪 .*? 只匹配最近的一对标签。
8.替换结果中包含正则特殊字符未转义
将 "1+1" 替换为 "2",但替换字符串写成 "1+1" 触发正则加法若使用正则模式,替换字符串中的 +、.、* 等需转义为 \+、\.、\*,或使用普通替换模式替换字符串本身不是正则,但若替换引擎将其解释为正则(如某些工具),则特殊字符需转义。普通替换模式则无此问题。
result = replace(input, pattern, replacement, mode)
input原始文本字符串pattern查找模式(普通文本或正则)replacement替换成的文本字符串mode替换模式:普通/正则/批量规则输入文本为 '2024-03-15 14:30:00',使用正则模式,pattern = '(\d{4})-(\d{2})-(\d{2})',replacement = '$3/$2/$1'。替换后结果为 '15/03/2024 14:30:00'。推导:正则捕获组 $1=2024, $2=03, $3=15,重组为日/月/年格式。
6 种主流语言实现,复制即用:
import re
# 普通替换:将 "cat" 替换为 "dog"
text = "The cat sat on the mat."
result = text.replace("cat", "dog")
print(result) # The dog sat on the mat.
# 正则替换:将所有数字替换为 "#"
text2 = "Order 123, price 45.67"
result2 = re.sub(r'\d+', '#', text2)
print(result2) # Order #, price #.#
# 批量规则:同时替换多个模式
rules = [
("cat", "dog"),
("mat", "rug"),
(r'\bthe\b', 'a') # 正则:单词边界
]
text3 = "The cat sat on the mat."
for pattern, replacement in rules:
if pattern.startswith(r'\b') or pattern.startswith(r'\d'):
text3 = re.sub(pattern, replacement, text3, flags=re.IGNORECASE)
else:
text3 = text3.replace(pattern, replacement)
print(text3) # a dog sat on a rug.// 普通替换:将 "cat" 替换为 "dog"
let text = "The cat sat on the mat.";
let result = text.replace("cat", "dog");
console.log(result); // The dog sat on the mat.
// 正则替换:将所有数字替换为 "#"
let text2 = "Order 123, price 45.67";
let result2 = text2.replace(/\d+/g, '#');
console.log(result2); // Order #, price #.#
// 批量规则:同时替换多个模式
let rules = [
{ pattern: "cat", replacement: "dog" },
{ pattern: "mat", replacement: "rug" },
{ pattern: /\bthe\b/gi, replacement: "a" } // 正则:单词边界,忽略大小写
];
let text3 = "The cat sat on the mat.";
for (let rule of rules) {
text3 = text3.replace(rule.pattern, rule.replacement);
}
console.log(text3); // a dog sat on a rug.package main
import (
"fmt"
"regexp"
"strings"
)
func main() {
// 普通替换:将 "cat" 替换为 "dog"
text := "The cat sat on the mat."
result := strings.ReplaceAll(text, "cat", "dog")
fmt.Println(result) // The dog sat on the mat.
// 正则替换:将所有数字替换为 "#"
text2 := "Order 123, price 45.67"
re := regexp.MustCompile(`\d+`)
result2 := re.ReplaceAllString(text2, "#")
fmt.Println(result2) // Order #, price #.#
// 批量规则:同时替换多个模式
type rule struct {
pattern string
replacement string
isRegex bool
}
rules := []rule{
{"cat", "dog", false},
{"mat", "rug", false},
{`\bthe\b`, "a", true},
}
text3 := "The cat sat on the mat."
for _, r := range rules {
if r.isRegex {
re := regexp.MustCompile(r.pattern)
text3 = re.ReplaceAllString(text3, r.replacement)
} else {
text3 = strings.ReplaceAll(text3, r.pattern, r.replacement)
}
}
fmt.Println(text3) // a dog sat on a rug.
}#!/bin/bash
# 普通替换:将 "cat" 替换为 "dog"(使用 sed)
text="The cat sat on the mat."
echo "$text" | sed 's/cat/dog/g'
# 输出: The dog sat on the mat.
# 正则替换:将所有数字替换为 "#"(使用 sed 扩展正则)
text2="Order 123, price 45.67"
echo "$text2" | sed -E 's/[0-9]+/#/g'
# 输出: Order #, price #.#
# 批量规则:同时替换多个模式(使用 sed 管道)
text3="The cat sat on the mat."
echo "$text3" | sed 's/cat/dog/g' | sed 's/mat/rug/g' | sed -E 's/\bthe\b/a/gi'
# 输出: a dog sat on a rug.import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class TextReplace {
public static void main(String[] args) {
// 普通替换:将 "cat" 替换为 "dog"
String text = "The cat sat on the mat.";
String result = text.replace("cat", "dog");
System.out.println(result); // The dog sat on the mat.
// 正则替换:将所有数字替换为 "#"
String text2 = "Order 123, price 45.67";
String result2 = text2.replaceAll("\\d+", "#");
System.out.println(result2); // Order #, price #.#
// 批量规则:同时替换多个模式
String text3 = "The cat sat on the mat.";
text3 = text3.replace("cat", "dog");
text3 = text3.replace("mat", "rug");
text3 = text3.replaceAll("\\bthe\\b", "a"); // 正则:单词边界
System.out.println(text3); // a dog sat on a rug.
}
}<?php
// 普通替换:将 "cat" 替换为 "dog"
$text = "The cat sat on the mat.";
$result = str_replace("cat", "dog", $text);
echo $result . "\n"; // The dog sat on the mat.
// 正则替换:将所有数字替换为 "#"
$text2 = "Order 123, price 45.67";
$result2 = preg_replace('/\d+/', '#', $text2);
echo $result2 . "\n"; // Order #, price #.#
// 批量规则:同时替换多个模式
$text3 = "The cat sat on the mat.";
$rules = [
['cat', 'dog', false],
['mat', 'rug', false],
['/\bthe\b/i', 'a', true], // 正则:单词边界,忽略大小写
];
foreach ($rules as $rule) {
if ($rule[2]) {
$text3 = preg_replace($rule[0], $rule[1], $text3);
} else {
$text3 = str_replace($rule[0], $rule[1], $text3);
}
}
echo $text3 . "\n"; // a dog sat on a rug.本工具处理的是文本内容,不是文件名。你需要把文件名列表复制到输入框(每行一个),然后在“查找”写“2023”、“替换为”写“2024”,点击替换就能一次改完所有行。如果文件名有规律,比如“2023_01.jpg”,也可以用正则把“^2023”替换成“2024”。改完后复制结果,再到文件管理器里重命名。
正则替换是精确匹配,常见翻车原因:1)特殊符号没转义,比如想把“.”替换成“-”,正则里“.”代表任意字符,要写成“\.”;2)贪婪模式匹配了不该匹配的内容,比如想删掉两个标签之间的内容,用了“<.*>”会从第一个<匹配到最后一个>,改用“<.*?>”或更精确的写法;3)捕获组没用好。建议先在“查找”框输入正则,看预览区高亮是否如预期,再点替换。
可以。用两条替换规则配合批量替换功能:第一条:查找“ ”(空格),替换为空;第二条:查找“-”,替换为空。如果空格和短横线同时存在,可以写一条正则:查找“[ -]”(方括号表示字符集,匹配空格或短横线),替换为空。这样所有手机号都会被清理成纯数字格式。注意:如果数据里还有其他不该删的空格,正则要写得更精确。
所有替换操作完全在浏览器本地执行,不会将输入文本上传到任何服务器。即使断网也能正常使用。所以敏感数据(如密码表、源代码、个人通讯录)可以放心处理。工具实现方式是纯前端 JavaScript,不依赖后端接口。
用普通替换做不到,因为它是全局匹配。可以用正则的“负向先行断言”或“负向后行断言”来排除特定上下文。例如,只替换后面不跟着“手机”的“苹果”,正则写“苹果(?!手机)”,替换为“香蕉”。如果“苹果”前面也可能有干扰词(如“红苹果”里的“苹果”想保留),则需更复杂的断言组合。建议先在预览区测试,确认高亮部分都是想替换的。
空行通常是因为原文本末尾有换行符,或者替换操作删除了某行全部内容后留下了空行。如果是前者,可以在替换前先把所有连续的换行符合并:用正则查找“\n\n+”(两个及以上换行),替换为“\n”。如果是后者(比如删除了所有“无效数据”这一行),替换后会在原位置留下空行,需要再执行一次“删除空行”操作——本工具没有内置这个按钮,但可以用正则查找“^\s*$”替换为空(注意要勾选“多行模式”)。
本工具没有“按列处理”功能。如果数据是 Tab 分隔的,可以分两步:第一步,用正则把每行的前几列“保护”起来。比如有两列,你想替换第二列的“旧值”为“新值”,可以先用正则查找“^([^\t]+\t)旧值”,替换为“$1新值”($1代表第一列及分隔符)。第二步,确认只改了第二列。如果列数固定但分隔符不是 Tab,将“\t”换成实际分隔符。更简单的方案:先在 Excel 里单独复制要改的那一列到本工具,改完再贴回去。
本工具没有撤销功能。每次点击“替换”都会直接修改输入框里的文本。建议操作前先复制一份原始数据到记事本或另一个标签页备份。如果已经替换了,可以尝试用同样的规则反向替换回来——例如把“香蕉”再替换回“苹果”,但前提是反向替换不会影响到文本里本来就有的“香蕉”。最保险的做法:每次只对一小部分数据做测试,确认规则正确后再处理全部。
普通替换就是“找一模一样的内容,换成另一个一模一样的内容”,比如把“abc”换成“xyz”,不会识别任何模式。正则替换则把“查找”框当成一种模式描述语言:比如“\d+”代表“连续的数字”,可以一次匹配“123”“4567”等所有数字串,然后统一替换。如果你的替换需求是“把第3到第5个字符删掉”“把邮箱地址隐藏中间部分”“把所有HTML标签去掉”,这些必须用正则。如果只是简单的文字替换,用普通替换更安全,不容易误伤。
隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。