-
-
Notifications
You must be signed in to change notification settings - Fork 926
Description
🐛 Description
When running a Flutter app on Flutter Web (especially on mobile browsers like iOS Safari), the app crashes with:
FormatException: Invalid regular expression: invalid group specifier name
The issue originates from this code in flutter_html:
static String _removeUnnecessaryWhitespace(String text) {
return text
.replaceAll(RegExp(r" *(?=\n)"), "")
.replaceAll(RegExp(r"(?<=\n) *"), "")
.replaceAll("\n", " ")
.replaceAll("\t", " ")
.replaceAll(RegExp(r" {2,}"), " ");
}
🔥 Root Cause
This RegExp uses a lookbehind assertion:
(?<=\n)
Flutter Web relies on the browser’s JavaScript RegExp engine, and lookbehind is not supported in many mobile browsers, including:
iOS Safari
Many Android WebViews
In-app browsers (e.g., WeChat)
When unsupported, the engine interprets (?<= as the start of a named capture group and throws:
invalid group specifier name
This results in a runtime crash on Web, even though the same code works on Android/iOS native.
✅ Web-Safe Equivalent
The same logic can be implemented without lookbehind:
static String _removeUnnecessaryWhitespace(String text) {
return text
// Remove spaces before newline
.replaceAll(RegExp(r" *\n"), "\n")
// Remove spaces after newline (lookbehind-free)
.replaceAll(RegExp(r"\n +"), "\n")
// Replace newline and tab with space
.replaceAll("\n", " ")
.replaceAll("\t", " ")
// Collapse multiple spaces
.replaceAll(RegExp(r" {2,}"), " ");
}
This produces equivalent behavior and works across all browsers.
🌍 Impact
Affects all Flutter Web builds
Particularly breaks mobile web users
Causes rendering failure when HTML parsing runs
💡 Suggestion
Avoid using lookbehind assertions in RegExp for Flutter Web compatibility.
Flutter Web RegExp behavior should be considered equivalent to JavaScript-level support, where lookbehind is not reliably available.
I can submit a PR with this change if the approach looks good.