Flutter鸿蒙开发:正则表达式工具详解
·
Flutter鸿蒙开发:正则表达式工具详解
欢迎加入开源鸿蒙跨平台社区! https://openharmonycrossplatform.csdn.net
一、前言
正则表达式是文本处理的强大工具,广泛应用于数据验证、内容提取等场景。本文将详细介绍如何在Flutter鸿蒙应用中实现正则表达式工具,包括规则匹配、结果提取和替换操作等内容。
二、效果展示



本组件实现了以下功能:
- 正则表达式测试
- 常用预设模板
- 匹配结果展示
- 分组提取
- 替换操作
- 语法参考
三、技术要点
3.1 正则表达式基础
// 创建正则表达式
final regex = RegExp(r'\d+');
// 检查是否匹配
final isMatch = regex.hasMatch('abc123');
// 查找所有匹配
final matches = regex.allMatches('abc123def456');
// 替换
final replaced = 'abc123'.replaceAll(regex, 'XXX');
3.2 匹配选项
RegExp buildRegex(String pattern, {
bool caseSensitive = true,
bool multiline = false,
bool dotAll = false,
}) {
return RegExp(
pattern,
caseSensitive: caseSensitive,
multiLine: multiline,
dotAll: dotAll,
);
}
3.3 分组提取
class MatchResult {
final String match;
final int start;
final int end;
final List<String> groups;
MatchResult({
required this.match,
required this.start,
required this.end,
required this.groups,
});
}
List<MatchResult> extractMatches(String input, RegExp regex) {
return regex.allMatches(input).map((m) {
return MatchResult(
match: m.group(0) ?? '',
start: m.start,
end: m.end,
groups: List.generate(
m.groupCount,
(i) => m.group(i + 1) ?? '',
),
);
}).toList();
}
四、完整实现
4.1 常用预设
class RegexPreset {
final String id;
final String name;
final String pattern;
RegexPreset(this.id, this.name, this.pattern);
}
final List<RegexPreset> presets = [
RegexPreset('email', '邮箱', r'[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}'),
RegexPreset('phone', '手机号', r'1[3-9]\d{9}'),
RegexPreset('idCard', '身份证', r'\d{17}[\dXx]'),
RegexPreset('url', 'URL', r'https?://[^\s]+'),
RegexPreset('ip', 'IP地址', r'((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)'),
RegexPreset('date', '日期', r'\d{4}[-/年]\d{1,2}[-/月]\d{1,2}[日]?'),
RegexPreset('time', '时间', r'\d{1,2}:\d{2}(:\d{2})?'),
RegexPreset('html', 'HTML标签', r'<[^>]+>'),
RegexPreset('chinese', '中文字符', r'[\u4e00-\u9fa5]+'),
RegexPreset('number', '数字', r'-?\d+(\.\d+)?'),
RegexPreset('hex', '十六进制', r'#[0-9A-Fa-f]{6}|#[0-9A-Fa-f]{3}'),
RegexPreset('whitespace', '空白字符', r'\s+'),
];
4.2 替换操作
String doReplace(String input, String pattern, String replacement) {
try {
final regex = RegExp(pattern);
return input.replaceAll(regex, replacement);
} catch (e) {
return input;
}
}
// 支持分组引用的替换
String replaceWithGroups(String input, String pattern, String replacement) {
final regex = RegExp(pattern);
return input.replaceAllMapped(regex, (match) {
String result = replacement;
for (int i = 0; i <= match.groupCount; i++) {
result = result.replaceAll('\$$i', match.group(i) ?? '');
}
return result;
});
}
4.3 错误处理
class RegexResult {
final bool success;
final List<MatchResult>? matches;
final String? error;
RegexResult.success(this.matches)
: success = true,
error = null;
RegexResult.error(this.error)
: success = false,
matches = null;
}
RegexResult testRegex(String pattern, String input) {
try {
final regex = RegExp(pattern);
final matches = extractMatches(input, regex);
return RegexResult.success(matches);
} catch (e) {
return RegexResult.error(e.toString());
}
}
五、界面实现
5.1 预设选择
Wrap(
spacing: 8,
runSpacing: 8,
children: presets.map((preset) {
final isSelected = selectedPreset == preset.id;
return ActionChip(
label: Text(preset.name),
backgroundColor: isSelected ? Colors.indigo.shade100 : null,
onPressed: () => loadPreset(preset),
);
}).toList(),
)
5.2 匹配选项
Wrap(
spacing: 16,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Checkbox(
value: caseSensitive,
onChanged: (v) {
setState(() => caseSensitive = v ?? true);
testMatch();
},
),
const Text('区分大小写'),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Checkbox(
value: multiline,
onChanged: (v) {
setState(() => multiline = v ?? false);
testMatch();
},
),
const Text('多行模式'),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Checkbox(
value: dotAll,
onChanged: (v) {
setState(() => dotAll = v ?? false);
testMatch();
},
),
const Text('.匹配换行'),
],
),
],
)
5.3 匹配结果展示
...List.generate(matches.length, (index) {
final match = matches[index];
return Container(
margin: const EdgeInsets.only(bottom: 8),
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.green.shade50,
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
decoration: BoxDecoration(
color: Colors.green.shade200,
borderRadius: BorderRadius.circular(12),
),
child: Text('#${index + 1}'),
),
const SizedBox(width: 8),
Expanded(
child: SelectableText(
match.match,
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
],
),
Text('位置: ${match.start} - ${match.end}'),
if (match.groups.isNotEmpty)
Wrap(
spacing: 8,
children: List.generate(match.groups.length, (i) {
return Chip(label: Text('组${i + 1}: ${match.groups[i]}'));
}),
),
],
),
);
})
六、正则表达式语法参考
6.1 基本语法
| 符号 | 说明 |
|---|---|
. |
匹配任意字符(除换行) |
\d |
匹配数字 [0-9] |
\w |
匹配字母数字下划线 |
\s |
匹配空白字符 |
^ |
匹配行首 |
$ |
匹配行尾 |
6.2 量词
| 符号 | 说明 |
|---|---|
* |
0次或多次 |
+ |
1次或多次 |
? |
0次或1次 |
{n} |
恰好n次 |
{n,m} |
n到m次 |
6.3 分组
| 符号 | 说明 |
|---|---|
(...) |
捕获分组 |
(?:...) |
非捕获分组 |
\1, \2 |
分组引用 |
七、最佳实践
7.1 性能优化
// 预编译常用正则表达式
final emailRegex = RegExp(r'[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}');
final phoneRegex = RegExp(r'1[3-9]\d{9}');
// 避免在循环中创建正则表达式
bool validateEmail(String input) {
return emailRegex.hasMatch(input);
}
7.2 安全处理
// 处理用户输入的正则表达式
RegExp? safeRegex(String pattern) {
try {
return RegExp(pattern);
} catch (e) {
return null;
}
}
7.3 复杂模式建议
// 使用命名分组提高可读性
final dateRegex = RegExp(
r'(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})'
);
// 使用详细模式(添加注释)
final regex = RegExp(r'''
^ # 行首
[\w.-]+ # 用户名部分
@ # @符号
[\w.-]+ # 域名部分
\. # 点号
[a-zA-Z]{2,} # 顶级域名
$ # 行尾
''', verbose: true);
八、总结
正则表达式工具是文本处理的利器。通过本文介绍的方法,开发者可以:
- 快速测试正则表达式
- 使用常用预设模板
- 提取匹配结果和分组
- 执行替换操作
在实际开发中,建议建立常用正则表达式库,提高开发效率。
九、参考资料
- 正则表达式30分钟入门教程
- Dart RegExp API
- 鸿蒙文本处理指南
更多推荐



所有评论(0)