想要正确的Regex从服务器的responsetext中提取文本,并对提取的文本执行JSON.parse


await page.on("response", async (response) => {
const request = await response.request();
if (
request.url().includes("https://www.jobs.abbott/us/en/search-results")
) {
const text = await response.text();
const root = await parse(text);
root.querySelectorAll("script").map(async function (n) {
if (n.rawText.includes("eagerLoadRefineSearch")) {
const text = await n.rawText.match(
/"eagerLoadRefineSearch":({.*}),/,
);
const refinedtext = await text[0].match(/[{.*}]/);
//console.log(refinedtext);
console.log(JSON.parse(refinedtext[0]));
}
});
}
});

在这个片段中,我发布了一个文本格式的数据,我想用regexeagerLoadRefineSearch : { (and its content too)}提取为文本,并对提取的文本执行json.parse,这样我最终得到一个"eagerLoadRefineSearch" : {}的json对象。

我使用puppetter拦截响应。我只想要一个正确的regex,它可以得到"eagerLoadRefineSearch" : {}的整个对象文本(及其内容(。

我正在此链接中共享来自服务器的响应文本https://codeshare.io/bvjzJA。

我想从中的文本格式的数据中提取"eagerLoadRefineSearch" : {}https://codeshare.io/bvjzJA

上下文

愚蠢的错误

您正在解析的文本在eagerLoadRefineSearch周围没有两侧的"。现在要匹配的对象跨越几行,因此需要m标志。此外,.与新线不匹配,因此备选方案是使用[sS]。请参阅如何在多行中使用javascript正则表达式。

另外,不要在字符串方法match上使用await

匹配右大括号

快速搜索这个话题会让我找到这个链接,正如我所怀疑的,这很复杂。为了缓解这个问题,我假设文本是正确缩进的。我们可以在缩进级别上进行匹配,以找到具有此模式的右大括号。

/(?<indent>[s]+){[sS]+k<indent>}/gm

如果左大括号和右大括号都处于相同的缩进级别,则此操作有效。它们不在我们的情况下,因为eagerLoadRefineSearch:位于缩进和左大括号之间,但我们可以解释这一点。

const reMatchObject = /(?<indent>[s]+)eagerLoadRefineSearch: {[sS]+?k<indent>}/gm

有效的JSON

如前所述,密钥缺少两侧双引号,因此让我们用"key"s替换所有keys。

const reMatchKeys = /(w+):/gm
const impure = 'hello: { name: "nammu", age: 18, subjects: { first: "english", second: "mythology"}}'
const pure = impure.replace(reMatchKeys, '"$1":')
console.log(pure)

然后我们去掉后面的逗号。下面是适用于这个示例的正则表达式。

const reMatchTrailingCommas = /,(?=s+[]}])/gm

一旦我们通过管道传输这些replace函数,JSON.parse就可以很好地使用这些数据。

代码

await page.on('response', async (response) => {
const request = await response.request();
if (
request
.url()
.includes('https://www.jobs.abbott/us/en/search-results')
) {
const text = await response.text();
const root = await parse(text);
root.querySelectorAll('script').map(async function (n) {
const data = n.rawText;
if (data.includes('eagerLoadRefineSearch')) {
const reMatchObject = /(?<indent>[s]+)eagerLoadRefineSearch: {[sS]+?k<indent>}/gm;
const reMatchKeys = /(w+):s/g;
const reMatchTrailingCommas = /,(?=s+[]}])/gm;
const parsedStringArray = data.toString().match(reMatchObject);
for (const parsed of parsedStringArray) {
const noTrailingCommas = parsed.replace(reMatchTrailingCommas, '');
const validJSONString = '{' + noTrailingCommas.replace(reMatchKeys, '"$1":') + '}';
console.log(JSON.parse(validJSONString));
}
}
});
}
});

最新更新