
1. 项目背景与核心功能设计正则表达式作为文本处理的瑞士军刀在Web开发和移动应用领域有着不可替代的作用。但它的语法晦涩难懂调试过程往往令人抓狂。这个基于Flutter和OpenHarmony的正则表达式工具App正是为了解决这一痛点而生。我在实际开发中经常遇到这样的场景写了一个复杂的正则表达式却不确定它是否能匹配目标文本或者想知道它会匹配哪些部分。传统的做法是反复修改代码、运行测试效率极低。这个工具App的核心价值就在于提供实时可视化的正则表达式测试环境。核心功能模块包括实时匹配引擎输入正则和文本后立即显示匹配结果可视化高亮用颜色标记匹配成功的文本片段替换操作支持正则替换并显示结果常用模板库内置10个高频使用的正则表达式语法速查内置正则表达式语法参考手册2. Flutter与OpenHarmony环境搭建2.1 Flutter开发环境配置开发这个工具App需要先配置Flutter开发环境。我推荐使用Flutter 3.41.9稳定版对应的Dart SDK版本是3.1.5。安装步骤如下# 下载Flutter SDK wget https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.41.9-stable.tar.xz # 解压到目标目录 tar xf flutter_linux_3.41.9-stable.tar.xz -C ~/development # 添加环境变量 echo export PATH$PATH:$HOME/development/flutter/bin ~/.bashrc source ~/.bashrc # 运行doctor检查环境 flutter doctor注意如果遇到you are applying flutters main gradle plugin imperatively using the apply s警告可以忽略不影响使用。这是Flutter Gradle插件的一个已知问题。2.2 OpenHarmony适配准备为了让Flutter应用能在OpenHarmony上运行需要配置鸿蒙版的Flutter SDK。macOS用户可以通过以下命令切换flutter channel openharmony flutter upgrade关键依赖项包括hispark wifi iot套件用于OpenHarmony设备连接hi3861开发板驱动如果使用润和智能小车开发套件OpenHarmony的hvigor构建工具3. 正则表达式核心功能实现3.1 实时匹配引擎设计匹配功能的核心是Dart的RegExp类。我们在StatefulWidget中维护两个TextEditingController分别处理正则表达式和测试文本的输入class _RegexTesterPageState extends StateRegexTesterPage { final TextEditingController _regexController TextEditingController(); final TextEditingController _textController TextEditingController(); ListRegExpMatch _matches []; void _testRegex() { try { final regex RegExp( _regexController.text, caseSensitive: _caseSensitive, multiLine: _multiLine, dotAll: _dotAll, ); _matches regex.allMatches(_textController.text).toList(); } catch (e) { setState(() _errorMessage 正则表达式语法错误); } } }实时匹配的关键是在文本变化时立即触发_testRegex()。我们通过监听Controller的onChanged事件实现TextField( controller: _regexController, onChanged: (_) _testRegex(), )3.2 高亮显示实现技巧匹配结果的高亮显示使用RichText和TextSpan组合实现。核心思路是将文本分为匹配和未匹配部分分别处理Widget _buildHighlightedText() { final text _textController.text; final spans TextSpan[]; int lastEnd 0; for (var match in _matches) { // 未匹配部分 spans.add(TextSpan( text: text.substring(lastEnd, match.start), style: TextStyle(fontFamily: monospace), )); // 匹配部分 spans.add(TextSpan( text: text.substring(match.start, match.end), style: TextStyle( backgroundColor: Colors.yellow[300], fontWeight: FontWeight.bold, ), )); lastEnd match.end; } // 剩余文本 spans.add(TextSpan( text: text.substring(lastEnd), style: TextStyle(fontFamily: monospace), )); return RichText(text: TextSpan(children: spans)); }3.3 正则选项的实用价值三个核心选项对正则行为影响巨大区分大小写(caseSensitive)默认true。设为false时[A-Z]也会匹配小写字母多行模式(multiLine)改变^和$的行为使其匹配每行的开始/结束而非整个字符串点匹配所有(dotAll)让.元字符也能匹配换行符这些选项通过Checkbox组件控制状态变化时立即重新匹配Widget _buildCheckbox(String label, bool value, Function(bool) onChanged) { return Row( children: [ Checkbox( value: value, onChanged: (v) { onChanged(v ?? false); _testRegex(); // 选项变化时立即重新匹配 }, ), Text(label), ], ); }4. 进阶功能实现与优化4.1 替换功能的完整实现替换功能基于String的replaceAll方法但增加了正则选项的支持String _getReplaceResult() { try { final regex RegExp( _regexController.text, caseSensitive: _caseSensitive, multiLine: _multiLine, dotAll: _dotAll, ); return _textController.text.replaceAll(regex, _replaceController.text); } catch (e) { return 替换错误: ${e.toString()}; } }UI层面提供替换文本输入框和执行按钮结果显示在可滚动的区域内TextField( controller: _replaceController, decoration: InputDecoration(labelText: 替换为), ), ElevatedButton( onPressed: () { final result _getReplaceResult(); Clipboard.setData(ClipboardData(text: result)); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(替换结果已复制到剪贴板)), ); }, child: Text(执行替换), ), SingleChildScrollView( child: SelectableText(_getReplaceResult()), )4.2 常用模板库的设计模板数据使用List存储每个模板包含名称、正则表达式和描述final templates [ { name: 手机号, regex: r^1[3-9]\d{9}$, desc: 匹配中国大陆手机号 }, { name: 邮箱, regex: r^[\w-\.]([\w-]\.)[\w-]{2,4}$, desc: 匹配电子邮箱地址 }, // 其他模板... ];模板列表使用ListView.builder渲染点击时自动填充到正则输入框ListView.builder( itemCount: templates.length, itemBuilder: (context, index) { return Card( child: ListTile( title: Text(templates[index][name]), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(templates[index][desc]), Text( templates[index][regex], style: TextStyle(fontFamily: monospace), ), ], ), onTap: () { _regexController.text templates[index][regex]; setState(() _selectedTab 0); // 切换到匹配标签 _testRegex(); }, ), ); }, )4.3 语法帮助的交互实现语法帮助以对话框形式呈现使用AlertDialog组件void _showHelp() { showDialog( context: context, builder: (context) AlertDialog( title: Text(正则表达式语法), content: SingleChildScrollView( child: Column( children: [ _buildHelpItem(., 匹配任意单个字符), _buildHelpItem(r\d, 匹配数字), _buildHelpItem(r\w, 匹配字母数字下划线), // 其他语法项... ], ), ), actions: [ TextButton( onPressed: () Navigator.pop(context), child: Text(关闭), ), ], ), ); } Widget _buildHelpItem(String syntax, String desc) { return Padding( padding: EdgeInsets.symmetric(vertical: 8), child: Row( children: [ Container( width: 80, padding: EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.grey[200], borderRadius: BorderRadius.circular(4), ), child: Text( syntax, style: TextStyle(fontFamily: monospace), ), ), SizedBox(width: 16), Expanded(child: Text(desc)), ], ), ); }5. 性能优化与调试技巧5.1 防抖处理优化性能实时匹配虽然用户体验好但频繁执行正则匹配可能导致性能问题。我们添加简单的防抖逻辑Timer? _debounceTimer; void _testRegex() { _debounceTimer?.cancel(); _debounceTimer Timer(Duration(milliseconds: 300), () { // 实际匹配逻辑... }); }5.2 错误处理与用户反馈正则表达式可能包含语法错误需要进行妥善处理void _testRegex() { setState(() { _matches []; _errorMessage ; try { final regex RegExp(_regexController.text); _matches regex.allMatches(_textController.text).toList(); } catch (e) { _errorMessage 正则表达式错误: ${e.toString().split(:).last.trim()}; } }); }在UI中显示错误信息if (_errorMessage.isNotEmpty) Text( _errorMessage, style: TextStyle(color: Colors.red), )5.3 测试文本编辑优化长文本编辑时提供全屏编辑对话框GestureDetector( onTap: () _showFullScreenEditor(context), child: _buildHighlightedText(), ) void _showFullScreenEditor(BuildContext context) { showDialog( context: context, builder: (context) AlertDialog( title: Text(编辑测试文本), content: TextField( controller: _textController, maxLines: 20, autofocus: true, ), actions: [ TextButton( onPressed: () { Navigator.pop(context); _testRegex(); }, child: Text(确定), ), ], ), ); }6. OpenHarmony适配经验分享6.1 解决hvigor构建错误在OpenHarmony上构建时可能遇到hvigor错误flutter hvigor error: failed :entry:defaultcompilearkts...解决方案是确保项目目录没有中文路径并检查openharmony相关依赖是否完整flutter clean flutter pub get flutter run -d openharmony6.2 鸿蒙版Flutter特性适配鸿蒙版的Flutter在UI渲染上有些差异需要注意部分Widget的渲染效果可能不同动画性能需要特别优化平台通道的调用方式有差异建议在鸿蒙真机上频繁测试早期发现问题。6.3 多端部署策略利用Flutter的跨平台特性可以一套代码同时部署到OpenHarmony和其他平台# pubspec.yaml flutter: uses-material-design: true assets: - assets/regex_templates.json关键是要抽象平台相关代码使用条件导入import package:flutter/foundation.dart show kIsWeb; void _copyToClipboard(String text) { if (kIsWeb) { // Web端复制逻辑 } else { // 移动端复制逻辑 Clipboard.setData(ClipboardData(text: text)); } }7. 项目扩展与进阶方向7.1 历史记录功能使用shared_preferences保存用户常用的正则表达式final prefs await SharedPreferences.getInstance(); await prefs.setStringList(regex_history, [..._history, _regexController.text]);7.2 性能测试模块添加正则表达式执行时间统计void _testRegex() { final stopwatch Stopwatch()..start(); // ...匹配逻辑 setState(() { _executionTime stopwatch.elapsedMilliseconds; }); }7.3 可视化正则构建器考虑添加图形化的正则表达式构建界面降低学习曲线。可以借鉴regexr.com的交互方式通过拖拽组件生成正则表达式。7.4 测试用例管理允许用户保存测试文本和预期结果形成测试用例集便于回归测试class RegexTestCase { final String name; final String pattern; final String testString; final ListString expectedMatches; // 保存到本地数据库 Futurevoid save() async { final db await DatabaseHelper.instance.database; await db.insert(test_cases, toMap()); } }8. 项目打包与发布8.1 Flutter打包注意事项打包OpenHarmony应用时需要确保包含必要的原生库flutter build apk --target-platform android-arm64如果遇到VC库缺失问题可以在windows上打包时添加flutter build windows --release8.2 应用商店发布发布到AppStore和各大应用市场的注意事项准备不同尺寸的应用截图编写详细的应用描述处理应用签名和证书适配不同的屏幕密度8.3 持续集成方案配置GitHub Actions实现自动化构建和测试name: Flutter CI on: [push, pull_request] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv2 - uses: subosito/flutter-actionv1 - run: flutter pub get - run: flutter test - run: flutter build apk --release9. 实际开发中的经验教训在开发这个正则表达式工具的过程中我积累了几个关键经验实时反馈至关重要最初版本需要手动点击测试按钮用户反馈很差。改为实时匹配后体验大幅提升。这告诉我工具类应用必须尽可能减少用户操作步骤。错误处理要友好早期版本遇到错误的正则表达式时会直接崩溃。后来添加了try-catch和友好的错误提示用户满意度明显提高。模板库的价值超预期原本以为模板只是锦上添花的功能但实际上80%的用户都是从模板开始使用的。这提醒我要更重视开箱即用的体验。性能优化需要平衡实时匹配虽然体验好但对复杂正则和长文本会有性能问题。最终采用防抖策略取得了不错的平衡。跨平台差异不容忽视在OpenHarmony上测试时发现了一些渲染差异这提醒我跨平台开发不能只在一个平台上测试。