我碰到了一個障礙。此代碼片段非常適合獲得電影評級(如果存在)。當它到達不包含正則運算式的記錄時,它會出錯。“TypeError:無法讀取 null 的屬性‘0’”
const ratingPass1 = /<span >/g;
const ratingPass2 = /(?<=<span >)/g;
for(var i = 0; i < 18; i )
{ var rating1String = results[i].match(ratingPass1);
Logger.log('content: ' rating1String[0]);
var rating2String = rating1String[0].match(ratingPass2);
--> error is here Logger.log('content: ' rating2String[0]);
我對 javascript 太陌生了,不知道如何在這段代碼中實作“包含”或“包含”或類似的東西。但是我對正則運算式的使用還算不錯,并且認為我可以將正則運算式變成一個包含包含組的大型排除組,所以我嘗試了:
const ratingPass1 = /(?:<span >)/g;
var rating1String = results[i].match(ratingPass1);
Logger.log('content: ' rating1String[0]);
但我不斷收到錯誤,我想我應該,因為我仍然在說“找到它,但它排除它”,我需要一個“如果你沒有找到它,就忽略它”。或許這就是“匹配”
var rating1String = results[i].match(ratingPass1);
Logger.log('content: ' rating1String[0]);
可以更改為類似 match OR ignore if null?
更新:花了好幾個小時,但我想出了一些辦法。可能只是僥幸,但至少它有效!
我用以下內容替換了變數和日志資訊:
var rating0String = "";
var rating1String = results[i].match(ratingPass1);
if(!ratingPass1){
Logger.log('content: ' rating0String);
}else{
Logger.log('content: ' rating1String);
};
var rating2String = results[i].match(ratingPass2);
if(!ratingPass2){
Logger.log('content: ' rating0String);
}else{
Logger.log('content: ' rating2String);
};
uj5u.com熱心網友回復:
使用兩個匹配相同文本兩次的正則運算式沒有什么意義,特別是因為您的第一個正則運算式已經包含一個圍繞您要提取的模式部分的捕獲組。只需在匹配物件上使用捕獲的索引即可。
你需要使用
const ratingPass = /<span >/g;
for (const result of results) {
const matches = result.matchAll(ratingPass);
for (const match of matches) {
Logger.log('rating1String: ' match[0]);
Logger.log('rating2String: ' match[1]);
}
}
這里,
<span >匹配<span vertical-align: inherit;">,然后捕獲任何零個或多個字符,但盡可能少地進入第 1 組(使用([\s\S]*?)),然后匹配">for (const result of results) {...}迭代一些results陣列const matches = result.matchAll(ratingPass)獲取每個result字串的所有匹配項for (const match of matches) {...}遍歷找到的匹配項match[0]是整個匹配值,match[1]是捕獲到組 1 中的部分。
分享腳本后更新
function DiaryImportMain() {
DiaryImportclearRecords();
const url = "https://letterboxd.com/tag/30-countries-2021/diary/";
const str = UrlFetchApp.fetch(url).getContentText();
const mainRegex = /<li >([\s\S]*?)<\/li>/gi;
const results = str.match(mainRegex);
const filmTitlePass = /height="225" alt="如果未找到常量則忽略(其中常量是正則運算式)"\/>/i;
const usernamePass = /<strong ><a href="\/(?:[\s\S]*?)\/">([\s\S]*?)<\/a><\/strong>/i;
const ratingPass = /<span >/i;
for(var i = 0; i < 18; i ) {
Logger.log('content: ' results[i]);
const filmTitle = (results[i].match(filmTitlePass) || ['','']);
const filmTitle1String = filmTitle[0];
Logger.log('content: ' filmTitle1String);
const filmTitle2String = filmTitle[1];
Logger.log('content: ' filmTitle2String);
const username = (results[i].match(usernamePass) || ['','']);
const username1String = username[0];
Logger.log('content: ' username1String);
const username2String = username[1];
Logger.log('content: ' username2String);
const rating = (results[i].match(ratingPass) || ['','']);
const rating1String = rating[0];
Logger.log('content: ' rating1String);
const rating2String = rating[1];
Logger.log('content: ' rating2String);
DiaryImportaddRecord(i 1, filmTitle2String, username2String, rating2String);
}
}
uj5u.com熱心網友回復:
可以使用 Cheerio 庫有效地完成,檢查代碼中不言自明的注釋:
function matchRating()
{
// TODO replace html with your data
const html = '<div><span ></span><span ></span><span ></span></div>';
// create Cheerio object
const $ = Cheerio.load(html);
const ratingPrefixForClass = 'rated-';
// select all spans with `rating` class
$(".rating").each((i, el) => {
let classAttr = $(el).attr('class');
// split class attribute to get list of class names, find one with needed prefix
let ratingClassSearch = classAttr.split(' ').find(cls => cls.indexOf(ratingPrefixForClass) === 0);
// if needed class with prefix found, log its name, and its name without prefix
if (ratingClassSearch)
{
console.log(ratingClassSearch, ratingClassSearch.substring(ratingPrefixForClass.length));
}
});
}
要點:
- 不要使用正則運算式來決議 HTML。
- 使用為 Google Apps Script 移植的Cheerio JS 庫。要安裝它,您需要將其添加為依賴項。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/432784.html
上一篇:一次下載多個檔案
