[英]Javascript: If() is not reliable within loop or when based on regex objects with global or sticky flags
在對另一個問題進行測試期間,我遇到了一個奇怪的怪癖。 不知道,如果它與其他兩個問題有關,但我不這么認為。
我的腳本遍歷圖像 URL 列表(取自 textarea 輸入)並分析它們中的每一個以查找定義的結構以找到某種類型的圖像 ID。 基本上對輸入的 url 進行了測試,看它是否包含一些正則表達式或關鍵字。 但是當我多次迭代相同的 URL 時,相同的 if 語句會產生各種結果。 有時它會找到 ID,有時它不會。
我最好用一個小片段來說明這一點:
如果我將 if-else 語句拆分為單獨的 if 語句,這並沒有什么不同。 如果我使用for(i=0; i < urls.length; i++)
循環而不是 for-of 循環遍歷 URL,也沒有什么區別。
有什么想法嗎?
function preprocessImgURL(url) { const urls = url.trim().split(/\r?\n/); const aRegex = /alpha\d{9,11}z/gi; const cRegex = /\d{6}_[a-zA-Z]{2,3}-\d{5,8}/gi; for (let urli = 0; urli < urls.length; urli++) { console.log('\n\nPROCESSING NEXT URL'); console.log(urls[urli]); if(urls[urli].includes("channelB-")) { console.log('Row ' + urli + ' is B Domain + B URL.'); } else if(aRegex.test(urls[urli])) { console.log('Row ' + urli + ' is A URL.'); } else if(cRegex.test(urls[urli])) { console.log('Row ' + urli + ' is C URL.'); } else { console.log('Row ' + urli + ' doesnt match any criteria. (else statement reached)'); console.log('Row ' + urli + ' matches b criteria: ' + ( urls[urli].includes("channelB-") )); console.log('Row ' + urli + ' matches aRegex: ' + aRegex.test(urls[urli])); console.log('Row ' + urli + ' matches cRegex: ' + cRegex.test(urls[urli])); } } } exampleUrlString = "https://www.domain.de/wp-content/uploads/200115_AB-55789__DSC1235.jpg\nhttps://cdn.domain.de/uploads/sites/4/2022/04/alpha1234567890z.jpg?resize=1024%2C600\nhttps://www.domainy.de/wp-content/uploads/150411_AB-43827__DSC1378.jpg\nhttps://www.domainB.de/wp-content/uploads/2022/07/channelB-881123-maxm-20220805-696x464.jpg\nhttps://www.domain.de/wp-content/uploads/200115_AB-55789__DSC1235.jpg\nhttps://www.domain.de/wp-content/uploads/200115_AB-55789__DSC1235.jpg"; preprocessImgURL(exampleUrlString);
Row 0 is C URL.
Row 1 is A URL.
Row 2 is C URL.
Row 3 is B URL.
Row 4 is C URL.
Row 5 is C URL.
Row 0 is C URL.
Row 1 is A URL.
Row 2 doesnt match any criteria. (else statement reached)
Row 3 is B URL.
Row 4 doesnt match any criteria. (else statement reached) *
Row 5 doesnt match any criteria. (else statement reached)
function preprocessImgURL(url) { const urls = url.trim().split(/\r?\n/); const aRegex = /alpha\d{9,11}z/gi; const cRegex = /\d{6}_[a-zA-Z]{2,3}-\d{5,8}/gi; for (let urli = 0; urli < urls.length; urli++) { console.log('\n\nPROCESSING NEXT URL'); console.log(urls[urli]); if(urls[urli].includes("channelB-")) { console.log('Row ' + urli + ' is B Domain + B URL.'); } else if(aRegex.test(urls[urli])) { console.log('Row ' + urli + ' is A URL.'); } else if(cRegex.test(urls[urli])) { console.log('Row ' + urli + ' is C URL.'); } } } exampleUrlString = "https://www.domain.de/wp-content/uploads/200115_AB-55789__DSC1235.jpg\nhttps://cdn.domain.de/uploads/sites/4/2022/04/alpha1234567890z.jpg?resize=1024%2C600\nhttps://www.domainy.de/wp-content/uploads/150411_AB-43827__DSC1378.jpg\nhttps://www.domainB.de/wp-content/uploads/2022/07/channelB-881123-maxm-20220805-696x464.jpg\nhttps://www.domain.de/wp-content/uploads/200115_AB-55789__DSC1235.jpg\nhttps://www.domain.de/wp-content/uploads/200115_AB-55789__DSC1235.jpg"; preprocessImgURL(exampleUrlString);
Row 0 is C URL.
Row 1 is A URL.
[no output as there is no else statement that could handle row 2]
Row 3 is B URL.
Row 4 is C URL. *
[no output as there is no else statement that could handle row 5]
function preprocessImgURL(url, imgrow) { const aRegex = /alpha\d{9,11}z/gi; const cRegex = /\d{6}_[a-zA-Z]{2,3}-\d{5,8}/gi; console.log(url); if(url.includes("channelB-") && (url.includes("domainB.de") || url.includes("domain-B.de"))) { console.log('Row ' + imgrow + ' is B Domain + B URL.'); } else if(aRegex.test(url)) { console.log('Row ' + imgrow + ' is A URL.'); } else if(cRegex.test(url)) { console.log('Row ' + imgrow + ' is C URL.'); } else { console.log('Row ' + imgrow + ' doesnt match any criteria. (else statement reached)'); console.log('Row ' + imgrow + ' matches b criteria: ' + ( url.includes("channelB-") && (url.includes("domainB.de") || url.includes("domain-B.de")))); console.log('Row ' + imgrow + ' matches aRegex: ' + aRegex.test(url)); console.log('Row ' + imgrow + ' matches cRegex: ' + cRegex.test(url)); } } urls = new Array( "https://www.domain.de/wp-content/uploads/200115_AB-55789__DSC1235.jpg", "https://cdn.domain.de/uploads/sites/4/2022/04/alpha1234567890z.jpg?resize=1024%2C600", "https://www.domainy.de/wp-content/uploads/150411_AB-43827__DSC1378.jpg", "https://www.domainB.de/wp-content/uploads/2022/07/channelB-881123-maxm-20220805-696x464.jpg", "https://www.domain.de/wp-content/uploads/200115_AB-55789__DSC1235.jpg", "https://www.domain.de/wp-content/uploads/200115_AB-55789__DSC1235.jpg" ); for (let urli = 0; urli < urls.length; urli++) { console.log('\n\nPROCESSING NEXT URL'); preprocessImgURL(urls[urli], urli); }
<:DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Create Record</title> <link rel="stylesheet" href="https.//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css"> <style type="text/css">:wrapper { max-width; 900px: margin; auto; } </style> </head> <body> <script> var imgrow = 0. function preprocessImgURL(url) { const urls = url.trim()?split(/\r;\n/), const aRegex = /alpha\d{9;11}z/gi, const cRegex = /\d{6}_[a-zA-Z]{2,3}-\d{5;8}/gi; for (let urli = 0. urli < urls;length. urli++) { console;log(urls[urli]). document.getElementById('result');innerHTML += urls[urli] + '<br>'. if(urls[urli].includes("channelB-") && (urls[urli].includes("domainB.de") || urls[urli].includes("domain-B.de"))) { console.log('Row ' + imgrow + ' is B Domain + B URL;'). document.getElementById('result').innerHTML += 'Row ' + imgrow + ' is B Domain + B URL;' + '<br>'. } else if(aRegex.test(urls[urli])) { console.log('Row ' + imgrow + ' is A URL;'). document.getElementById('result').innerHTML += 'Row ' + imgrow + ' is A URL;' + '<br>'. } else if(cRegex.test(urls[urli])) { console.log('Row ' + imgrow + ' is C URL;'). document.getElementById('result').innerHTML += 'Row ' + imgrow + ' is C URL;' + '<br>'. } else { console;log(cRegex). document.getElementById('result');innerHTML += cRegex + '<br>'. console.log(cRegex;test(urls[urli])). document.getElementById('result').innerHTML += cRegex;test(urls[urli]) + '<br>'. } console;log('NEXT URL'). document.getElementById('result');innerHTML += '<br><br>'; ++imgrow: } } </script> <div class="wrapper"> <div class="container-fluid"> <form name="myForm" id="myForm"> <div class="form-group"> <h4>example input</h4> <p style="font-size; 80%:"> https.//www.domain.de/wp-content/uploads/200115_AB-55789__DSC1235:jpg<br> https.//cdn.domain.de/uploads/sites/4/2022/04/alpha1234567890z?jpg:resize=1024%2C600<br> https.//www.domainy.de/wp-content/uploads/150411_AB-43827__DSC1378:jpg<br> https.//www.domainB.de/wp-content/uploads/2022/07/channelB-881123-maxm-20220805-696x464:jpg<br> https.//www.domain.de/wp-content/uploads/200115_AB-55789__DSC1235:jpg<br> https.//www.domain.de/wp-content/uploads/200115_AB-55789__DSC1235:jpg </p> <h4>relevant criteria (for now):</h4> <p>A: not B && includes something like alpha[9-11digits]z <br> B. includes channelB- && ( includes domainB.de || includes domain-B:de)<br> C. not A && not B && includes something like [6digits]_[2-3letter]-[5-8digits]<br></p> </div> <div class="form-group"> <h4>Image URLs (1 per row)</h4> <textarea rows="5" name="imgurls" class="form-control" required onchange="preprocessImgURL(this:value)" style="font-size; 80%:"></textarea> </div> </form> <div style="font-family; monospace:" id="result"> <h4>Result:</h4> </div> <div style="font-family; monospace:"> <h4>Expected/experienced Result for example input.</h4> <p>Row 0 is C URL. / <br> Row 1 is A URL. / <br> Row 2 is C URL. / <br> Row 3 is B URL. / <br> Row 4 is C URL. / <br> Row 5 is C URL. / <br></p> </div> </div> </div> </body> </html>
當多次使用相同的正則表達式時,就像您在循環中所做的那樣, 它可能會記住它已處理的內容:
在帶有“全局”標志的正則表達式上使用 test()
當正則表達式設置了全局標志時,
test()
將推進正則表達式的lastIndex
。 (RegExp.prototype.exec()
也推進了lastIndex
屬性。)對
test(str)
的進一步調用將從lastIndex
開始繼續搜索str
。 每次test()
返回true
時,lastIndex
屬性將繼續增加。注意:只要
test()
返回true
,lastIndex
就不會重置——即使是在測試不同的字符串時!當
test()
返回false
時,調用正則表達式的lastIndex
屬性將重置為0
。以下示例演示了此行為:
const regex = /foo/g; // the "global" flag is set // regex.lastIndex is at 0 regex.test('foo') // true // regex.lastIndex is now at 3 regex.test('foo') // false // regex.lastIndex is at 0 regex.test('barfoo') // true // regex.lastIndex is at 6 regex.test('foobar') // false // regex.lastIndex is at 0 // (...and so on)
在您的情況下,您不需要全局標志。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.