v3: rich content meta regex improvements
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 42s

This commit is contained in:
khannurien
2026-06-27 14:34:47 +00:00
parent 96c41f01da
commit 88f1eb3d03

View File

@@ -139,25 +139,35 @@ function decodeHtmlEntities(str: string): string {
);
}
/**
* Find the first `<meta>` tag whose `attr` equals `value` and return its
* `content` (either attribute ordering). Each tag is matched in isolation so
* the `content` capture can never span across tag boundaries.
*/
function extractMetaContent(
html: string,
attr: string,
value: string,
): string | undefined {
const escaped = value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const keyRe = new RegExp(`\\b${attr}=["']${escaped}["']`, "i");
const contentRe = /\bcontent=(["'])([\s\S]*?)\1/i;
const tagRe = /<meta\b[^>]*>/gi;
let m: RegExpExecArray | null;
while ((m = tagRe.exec(html)) !== null) {
const tag = m[0];
if (!keyRe.test(tag)) continue;
const content = contentRe.exec(tag);
if (content) return decodeHtmlEntities(content[2]);
}
return undefined;
}
export function extractOgTag(
html: string,
tag: string,
): string | undefined {
const patterns = [
new RegExp(
`<meta[^>]+property=["']og:${tag}["'][^>]+content=(["'])([\\s\\S]*?)\\1`,
"i",
),
new RegExp(
`<meta[^>]+content=(["'])([\\s\\S]*?)\\1[^>]+property=["']og:${tag}["']`,
"i",
),
];
for (const pattern of patterns) {
const match = html.match(pattern);
if (match) return decodeHtmlEntities(match[2]);
}
return undefined;
return extractMetaContent(html, "property", `og:${tag}`);
}
/** Extract content from `<meta name="…" content="…">` (both attribute orderings). */
@@ -165,22 +175,7 @@ export function extractMetaName(
html: string,
name: string,
): string | undefined {
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const patterns = [
new RegExp(
`<meta[^>]+name=["']${escaped}["'][^>]+content=(["'])([\\s\\S]*?)\\1`,
"i",
),
new RegExp(
`<meta[^>]+content=(["'])([\\s\\S]*?)\\1[^>]+name=["']${escaped}["']`,
"i",
),
];
for (const pattern of patterns) {
const match = html.match(pattern);
if (match) return decodeHtmlEntities(match[2]);
}
return undefined;
return extractMetaContent(html, "name", name);
}
/** Extract the text content of the `<title>` element. */