diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx
index da484bd..43b63a2 100644
--- a/src/app/plugins/react-custom-html-parser.tsx
+++ b/src/app/plugins/react-custom-html-parser.tsx
@@ -31,7 +31,7 @@ import {
mxcUrlToHttp,
} from '../utils/matrix';
import { getMemberDisplayName } from '../utils/room';
-import { EMOJI_PATTERN, sanitizeForRegex, URL_NEG_LB } from '../utils/regex';
+import { EMOJI_REG_G, sanitizeForRegex } from '../utils/regex';
import { getHexcodeForEmoji, getShortcodeFor } from './emoji';
import { findAndReplace } from '../utils/findAndReplace';
import {
@@ -48,8 +48,6 @@ import { openExternalUrl } from '../utils/tauri';
const ReactPrism = lazy(() => import('./react-prism/ReactPrism'));
-const EMOJI_REG_G = new RegExp(`${URL_NEG_LB}(${EMOJI_PATTERN})`, 'g');
-
/**
* Click handler for external links - uses Tauri shell on desktop/mobile
*/
diff --git a/src/app/utils/findAndReplace.ts b/src/app/utils/findAndReplace.ts
index a4bd1ed..c76efa6 100644
--- a/src/app/utils/findAndReplace.ts
+++ b/src/app/utils/findAndReplace.ts
@@ -13,13 +13,18 @@ export const findAndReplace = (
const result: Array = [];
let lastEnd = 0;
+ regex.lastIndex = 0;
let match: RegExpExecArray | RegExpMatchArray | null = regex.exec(text);
while (match !== null && typeof match.index === 'number') {
result.push(convertPart(text.slice(lastEnd, match.index), result.length));
result.push(replace(match, result.length));
lastEnd = match.index + match[0].length;
+ if (match[0].length === 0) {
+ regex.lastIndex += 1;
+ }
if (regex.global) match = regex.exec(text);
+ else break;
}
result.push(convertPart(text.slice(lastEnd), result.length));
diff --git a/src/app/utils/regex.ts b/src/app/utils/regex.ts
index 0b98b0e..f46d076 100644
--- a/src/app/utils/regex.ts
+++ b/src/app/utils/regex.ts
@@ -14,13 +14,25 @@ export const EMAIL_REGEX =
export const URL_NEG_LB = '(?