簡體   English   中英

從字符串中提取 object

[英]Extracting object from string

我有一個來自 Webdriver.io 網站的示例腳本,類似於這樣(為測試而修改)

const { remote } = require('webdriverio');
var assert = require('assert');

;(async () => {
        const browser = await multiremote({
            capabilities: {
                browserName: 'chrome',
            },
            capabilities: {
                browserName: 'firefox'
            }
    })
    await browser.url('https://www.google.com');
    var title = await browser.getTitle();
    assert.equal(title, 'Google');
    await browser.deleteSession()
})()

我需要從中提取capabilities.browserName ,到目前為止我能夠像這樣提取它們

var browsers = str.match(/\scapabilities\s*?:\s*?\{[^{}]+\}/gi); // find capabilities
console.log(browsers.length); // check length
for(let i=0; i < browsers.length; i++){
    let b = browsers[i].replace(/\scapabilities\s*?:\s*?/, '') // remove capabilities: part
                       .replace(/'/g, '"' ) // convert single quote to double quote
                       .replace(/\s/g, '') // remove spaces, new lines, tabs etc.
                       .replace(/(\w+:)|(\w+ :)/g, function(matchedStr) { // wrap words in double quote as keys are not wrapped
                            return '"' + matchedStr.substring(0, matchedStr.length - 1) + '":';
                          });

    let browser = JSON.parse(b); // parse the string to convert to object
    console.log(browser.browserName); // Success !!!
}

這可以正常工作,但某些時間功能可能具有嵌套屬性,例如

capabilities: {
   browserName: 'chrome',
   proxy: {
     proxyType: 'PAC',
     proxyAutoconfigUrl: 'http://localhost:8888',
   }
},

這破壞了我的代碼,只返回一個瀏覽器firefox await multiremote()也可以是await remote()

提前致謝

如果我們可以假設在傳遞給remotemultiremote的 object 文字中沒有括號,那么我們可以通過匹配 ZC1C425268E68385D1AB66Z 調用的括號之間的所有內容來捕獲整個 object 文字。

我不會通過嘗試將 JavaScript object 文字語法轉換為 Z0ECD11C1D7A287401D8ZA7A8 的努力來實現 go。 相反,我們可以假設browserName屬性暗示它們出現在capabilities對象中,並且只匹配后面的browserName鍵和值(用單引號括起來)。

這是如何運作的:

 const str = `const { remote } = require('webdriverio'); var assert = require('assert'); ;(async () => { const browser = await multiremote({ myChromeBrowser: { capabilities: { browserName: 'chrome' } }, myFirefoxBrowser: { capabilities: { browserName: 'firefox' } } }) await browser.url('https://www.google.com'); var title = await browser.getTitle(); assert.equal(title, 'Google'); await browser.deleteSession() })()`; // find object literal, assuming it has no parentheses: const browsers = str.match(/\bawait\s+(multi)?remote\s*\((.*?)\)/gs) // find browserName properties with single quoted string values: ?.[0]?.match(/\bbrowserName\s*:\s*'[^']*/g) // extract the corresponding values: ?.map(m => m.split("'")[1]); console.log(browsers);

您可以編寫一個使用{}來檢查嵌套深度的快速解析器。 這假設沒有{字符出現在引號中,鍵沒有被引用,並且值用單引號引起來,所以它不是為處理所有邊緣情況而設計的,只處理您在此處提供的那些情況。

 const s = `const { remote } = require('webdriverio'); var assert = require('assert'); ;(async () => { const browser = await multiremote({ capabilities: { browserName: 'chrome', }, capabilities: { browserName: 'firefox' }, capabilities: { browserName: 'chrome', proxy: { proxyType: 'PAC', proxyAutoconfigUrl: 'http://localhost:8888', } }, }) await browser.url('https://www.google.com'); var title = await browser.getTitle(); assert.equal(title, 'Google'); await browser.deleteSession() })()`; const results = []; const re = /\bcapabilities: *{/g; for (let match; match = re.exec(s);) { let braces = 0, i = match.index; for (; i < s.length; i++) { if (s[i] === "{") { braces++; } else if (s[i] === "}") { if (--braces <= 0) { i++; break; } } } results.push( s.slice(match.index, i).match(/\bbrowserName: *'([^']*)'/)[1] ); } console.log(results);

另外,請記住您的原始字符串有兩個capabilities鍵,因此在 memory 的 object 中只有第二個存在。 我認為這是將源字符串調整為 SO 的人工制品,所以我沒有費心在這里調整它,而是簡單地拍了三分之一以顯示對問題的 scope 的解析工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM