php
  • regex
  • xpath
  • 2015-02-06 43 views 1 likes 
    1

    的,這是有用的,因爲我然後可以例如這樣做:
    xPath->query('//div.class');添加類縮寫成XPATH與使用正則表達式

    所以我需要正則表達式,其執行此變換:

    實施例1
    text().some_class => text()[contains(concat(" ", @class, " "), " some_class ")]
    例2:無關 - 這是在單引號
    @src = 'obr.gif' => @src = 'obr.gif'
    例3
    *.class => *[contains(concat(" ", @class, " "), " class ")]
    例4
    div.class => div[contains(concat(" ", @class, " "), " class ")]
    例5:什麼也不做 - 缺失問題,這應該有這個類(我知道,這不是有效的XPath)
    div[.neco] => div[.neco]

    我用PHP的preg_replace這樣:

    preg_replace(
         '/\.([a-z_][\w-]*)/i', 
         '[contains(concat(" ", @class, " "), " $1 ")]', 
         $xPath); 
    

    這只是工作的實例1號,3號和4。所以我更新了它:

    preg_replace(
         '/(?<=[\w*\])])\.([a-z_][\w-]*)/i', 
         '[contains(concat(" ", @class, " "), " $1 ")]', 
         $xPath); 
    

    然後只有沒有2沒有工作。我嘗試這樣做:

    preg_replace(
         '/(\'[^\']+\'.*?)*(?<=[\w*\])])\.([a-z_][\w-]*)/i', 
         '$1[contains(concat(" ", @class, " "), " $2 ")]', 
         $xPath); 
    

    ,對於作品:
    //div[@src = 'obr.gif'].class => //div[@src = 'obr.gif'][contains(concat(" ", @class, " "), " class ")]
    但(第2號),其這樣做不對:
    @src = 'obr.gif' => @src = 'obr[contains(concat(" ", @class, " "), " gif ")]'
    我意識到PHP力圖至少匹配的東西,所以「忽略「第一個括號,但我不知道,如何使正則表達式根據我的工作。

    PS:我只在xPath表達式中使用單引號,因此我不在乎引號。

    編輯:修改funkwurm答案PHP

    preg_replace_callback(<<<'CLASS' 
         /('|").*?(?<!\\)\1|(?<=[\w*\])])\.([a-z_][\w-]*)/i 
    CLASS 
         , function($matches) { 
          return $matches[1] ? $matches[0] : "[contains(concat(\" \", @class, \" \"), \" $matches[2] \")]"; 
         }, 
         $xPath 
    ); 
    

    我使用正則表達式入門nowdoc語法,因爲那時我沒有處理的帶引號的字符串逃脫。

    回答

    0

    這裏最好的方法是使用一個「匹配此除非條件A | B」方法進一步解釋here和用一個例子here

    我會做的正則表達式,像這樣:

    ('|")(?:(?!\\|\1).|\\.)*\1|([\w*\])])\.([a-z_][\w-]*) 
    

    Regular expression visualization

    Debuggex Demo

    在你的編程語言,你再查第二捕獲組是否具有任何內容。如果是這樣,那麼這是一個類,你想做你現有的替代。否則你不想做任何事情,這可能意味着你用比賽本身來取代它。下面的JavaScript實現。請注意,我得到匹配m,引用q的捕獲組,.之前的最後一個字符e和類別c的捕獲組。如果c未定義,則返回整個比賽m。否則我做替換。

    var xpaths = [ 
     
        'text().some_class',   // => text()[contains(concat(" ", @class, " "), " some_class ")] 
     
        '@src = \'obr.gif\'',   // => @src = 'obr.gif' 
     
        '*.class',      // => *[contains(concat(" ", @class, " "), " class ")] 
     
        'div.class',     // => div[contains(concat(" ", @class, " "), " class ")] 
     
        'div[.neco]',     // => div[.neco] 
     
        'div[@src = \'obr.gif\'].class',// => div[@src = 'obr.gif'][contains(concat(" ", @class, " "), " class ")] 
     
        'div[.//img.class]'    // => div[.//img[contains(concat(" ", @class, " "), " class ")]] 
     
    ]; 
     
    
     
    document.getElementById('out').value=xpaths.map(function(str) { 
     
        return str.replace(/('|")(?:(?!\\|\1).|\\.)*\1|([\w*\])])\.([a-z_][\w-]*)/ig, function(m, q, e, c) { 
     
        return (c==undefined)?m:(e+'[contains(concat(" ", @class, " "), " ' + c + ' ")]'); 
     
        }); 
     
    }).join('\n');
    <textarea id="out" rows="10" style="width:100%"></textarea>

    +0

    感謝您對維修類匹配規則(下劃線)。 :-)但是我不明白這個'\ [[^]] * \]'替代方法,因爲它導致這個xPath表達式'div [.// img.class]'失敗,其中圖像類不是處理。 – Velda 2015-02-06 14:52:15

    +0

    謝謝你,我可以修改你的正則表達式來處理以前的案例,並稍微簡化它,使用後視。我刪除了'\ [[^ \]] * \]'部分,而不是我加回'(?<= [\ w * \])])''。這解決了以前的情況。這部分'(['「])(?:(?!\\ | \ 1)。| \\。)* \ 1'我簡化爲'('|」)。*?(?<!\\) \ 1'更短,因此更容易理解(我希望它幾乎相當於)。你的解決方案處理雙引號和逃脫報價,很好。 :-) – Velda 2015-02-06 15:30:26

    +0

    啊,我認爲'[]'之間的任何東西都會被認爲不是一個班級。但是檢查它是否以'[\ w * \]開頭)''也可以,我改變了我的答案,讓它在JavaScript中工作而不會有後顧之憂。如果我的回答對你有幫助,你能點擊「接受」嗎?它可以幫助我們和網站:) – funkwurm 2015-02-06 16:22:17

    相關問題