[IR] XPath for Search Query

XPath 1.0node

XPath Containment程序員

Distributed Query Evaluation正則表達式

RE and DFA算法


 

XPath 1.0 

-- 在XML中的使用shell

 

XPath 語法: http://www.w3school.com.cn/xpath/xpath_syntax.aspexpress

 

XPath (紅色字體) 示例:編程

/bib/book/year Result: <year> 1995 </year>
 <year> 1998 </year>

/bib/paper/year Result: empty

XPath: Restricted Kleene Closure 暴力查找node的感受網絡

//author Result: <author> Serge Abiteboul </author>
 <author> <first-name> Rick </first-name>
 <last-name> Hull </last-name>
 </author>
 <author> Victor Vianu </author>
 <author> Jeffrey D. Ullman </author>

/bib//first-name Result: <first-name> Rick </first-name>

XPath: Text Nodes 提取 (無子結構的) elemapp

/bib/book/author/text()
Result: Serge Abiteboul
        Victor Vianu
        Jeffrey D. Ullman

XPath: Text Nodes 提取 (有子結構的) elemless

//author/* Result: <first-name> Rick </first-name>
 <last-name> Hull </last-name>

XPath: Attribute Nodes 提取屬性的內容

/bib/book/@price
Result: 「55」

XPath: Qualifiers 只要有firstname子節點的元素

/bib/book/author[firstname] Result: <author> <first-name> Rick </first-name>
 <last-name> Hull </last-name>
 </author>

XPath: Qualifiers 只要條件爲:有firstname子節點和address子節點,且address中下的某一level中有zip節點,以及下一level就得有city。知足如此條件的author下的lastname的內容。

/bib/book/author[firstname][address[//zip][city]]/lastname Result: <lastname> ... </lastname>
 <lastname> ... </lastname>

XPath: 子節點的屬性知足指定條件

/bib/book[@price < 「60」] /bib/book[author/@age < 「25」]

XPath: author下的elem只容許有txt。

/bib/book[author/text()]

  

XPath 軸軸可定義相對於當前節點的節點集

軸可定義相對於當前節點的節點集。

軸名稱 結果
ancestor 選取當前節點的全部先輩(父、祖父等)。
ancestor-or-self 選取當前節點的全部先輩(父、祖父等)以及當前節點自己。
attribute 選取當前節點的全部屬性。
child 選取當前節點的全部子元素。
descendant 選取當前節點的全部後代元素(子、孫等)。
descendant-or-self 選取當前節點的全部後代元素(子、孫等)以及當前節點自己。
following 選取文檔中當前節點的結束標籤以後的全部節點。
namespace 選取當前節點的全部命名空間節點。
parent 選取當前節點的父節點。
preceding 選取文檔中當前節點的開始標籤以前的全部節點。
preceding-sibling 選取當前節點以前的全部同級節點。
self 選取當前節點。

 


 

XPath Containment

Return Node: [[name]] 使用double circles表示。

任意深度子目錄存在:雙斜線。

 

表達式解釋:

root下的任意未知結點person,知足孩子中有name,任意子孫中需有屬性zip = "12345"的結點。

知足以上條件,則返回這個person的phone。

 

 

Equivalence, Containment 

    • E = E’ if they return the same result
    • E ⊆ E’ if the result returned by E is a subset of that returned by E’.

 

返回的結果老是一致的,咱們認爲這是一個query

 

這個比較複雜,因此咱們引入一種方法來解決:

Practical Algorithm for Linear XPath *,//

關鍵在於找到mapping。

 

第一個例子:

 

 第二個例子:

 

第三個例子:

爲什麼不等價?

應該是前者包含後者!

注意1/*// 轉化爲雙線。

注意2//name 這裏沒有*,因此是>=0,這致使了二者不等價!

 

 

Branching XPath *,//

  -- 難度加大,計算量大

視狀況而定,此處略。

 


 

Distributed Query Evaluation

a.b*.c    // any num of b, here we regard it as a Query.

a.b+.c    // at least one num of b

Review 正則表達式 與 DFA 的關係

在分佈式環境下的Query,以下:(如用在下圖中查詢這個Query)

 

 

A naïve approach takes too many communication steps

=> we have to do more work locally

A better approach needs to

1. identify all external references

2. identify targets of external references

 

Algorithm:

1. Given a query, we compute its automaton 計算出某一個query的對應的一個東西
2. Send it to each site 將這個東西分發給各個site
3. Start an identical process at each site 各個site分別處理這個東西
4. Compute two sets Stop(n, s) and Result(n, s) 計算出這兩個結果
5. Transmits the relations to a central location and get their union 合併全部結果

 

Detail:

每一個site都會有本身的一個《進出表》,以下:

Site 1:

In x1, x4
Out y1, y3

 

Site 2:

In y1, y3
Out z2

 

Site 3:

In z2
Out x4

 

相對於Query: a.b+.c 

Site 2 爲例,該site將處理query並獲得以下兩個table:

 

《搞不定表》- Stop Table

Start End
(y1, s2) (z2, s2)
(y3, s2) (z2, s2)

這裏的z2怎麼得來?Site 2雖然不曉得其餘site的信息,但起碼知道

與本身有直接鏈接的node信息。好比:

與y3直接相鏈接的z2有可能做爲s2

《能搞定表》- Result Table

Start End
(y1, s2) (y3, s3)
(y1, s3) (y1, s3)
(y3, s3) (y3, s3)

 

而後,每一個site都應該返回了針對該query的倆表。

接下來就是如何合併這麼些個表的問題。

讓咱們將整個表都列出來,作一次傻瓜式的demo。

Union:

Start Stop   Start Result  
(x1, s1) (y1, s2) stop1 (x1, s3) x1 result1
(x4, s2) (y3, s3) stop2  (x4, s2) x3 result2 
(y1, s2) (z2, s2) stop3  (x4, s3) x4 result3 
(y3, s2) (z2, s2) stop4  (y1, s2) y3 result4 
(z2, s2) (x4, s2) stop5  (y1, s3) y1 result5 
      (y3, s3) y3 result6 
      (z2, s1) z3 result7 
      (z2, s2) z2 result8 
      (z2, s3) z2 result9 

解說:

root    
stop1 在其餘site能直接終止麼?  
result4 還真有,能夠直接結束 匹配到了(y1,s2)
stop3 不結束,繞一繞,其餘site或許能給出新的sol 匹配到了(y1,s2)
result8 確實有,能夠直接結束 匹配到了(z2,s2)
stop5 不結束,繞一繞,其餘site或許能給出新的sol 匹配到了(z2,s2)
result2 還真有,能夠直接結束 匹配到了(x4,s2)
stop2 不結束,繞一繞,其餘site或許能給出新的sol 匹配到了(x4,s2)
result6 有的啦,能夠直接結束  
n/a 不結束,繞一繞,其餘site或許能給出新的sol 匹配不到了!

Answer:

{y3, z2, x3}

 


 

Regular Expression (正則表達式)

定義:

This definition may seem circular, but 1-3 form the basis
Precedence: Parentheses have the highest precedence,
followed by *, concatenation, and then union.

 

RE Examples (表達形式 = 實際的集合形式)

  -- 當search時但願return results in this kind of pattern.

• L(001) = {001}
• L(0+10*) = { 0, 1, 10, 100, 1000, 10000, … }  // union: or; * any number of 0
• L(0*10*) = {1, 01, 10, 010, 0010, …} i.e. {w | w has exactly a single 1}
• L( |- |- )* = {w | w is a string of even length}
• L((0(0+1))*) = { ε, 00, 01, 0000, 0001, 0100, 0101, …}
• L((0+ε)(1+ ε)) = {ε, 0, 1, 01}
• L(1Ø) = Ø ; concatenating the empty set to any set yields the empty set.
• Rε    = R  // ε就像1
• R+Ø = R  // 空集就像0

 

Exercise 1

∑ = {10, 11}, ∑* = {є, 10, 11, 1010, 1011, 1110, 1111, …}

表示集合裏元素的數量各自都是任意的,而後組合在一塊兒。

 

Exercise 2

L1 = {10, 1}, L2 = {011, 11}, L1L2 = {10011, 1011, 111}

哄小孩的題。

 

Exercise 3 

Write RE for
  – All strings of 0’s and 1’s (其實就是任意0與1的組合)

    • (0|1)*

  – All strings of 0’s and 1’s with at least 2 consecutive 0’s (須要至少有連續的0)

    • (0|1)*00(0|1)*

  – All strings of 0’s and 1’s beginning with 1 and not having two consecutive 0’s (不能有連續的0)

    • (1+10)*    // {1, 10} 其中的元素任意組合確實不會有連續的0出現,技巧哉!

 

More exercises

1) (0|1)*011
  • Answer: all strings of 0’s and 1’s ending in 011
2) 0*1*2*
  • Answer: any number of 0’s followed by any number of 1’s followed by any number of 2’s
3) 00*11*22*
  • Answer: strings in 0*1*2 with at least one of each symbo

 

 

Link: 百度百科

起源:

正則表達式的「鼻祖」或許可一直追溯到科學家對 人類神經系統工做原理的早期研究。美國新澤西州的Warren McCulloch和出生在美國底特律的Walter Pitts這兩位神經生理方面的科學家,研究出了一種用數學方式來描述神經網絡的新方法,他們創造性地將神經系統中的神經元描述成了小而簡單的自動控制元,從而做出了一項偉大的工做革新。
在1951 年,一位名叫Stephen Kleene的數學科學家,他在Warren McCulloch和Walter Pitts早期工做的基礎之上,發表了一篇題目是《神經網事件的表示法》的論文,利用稱之爲正則集合的數學符號來描述此模型,引入了正則表達式的概念。正則表達式被做爲用來描述其稱之爲「正則集的代數」的一種表達式,於是採用了「正則表達式」這個術語。
以後一段時間,人們發現能夠將這一工做成果應用於其餘方面。Ken Thompson就把這一成果應用於計算搜索算法的一些早期研究,Ken Thompson是 Unix的主要發明人,也就是大名鼎鼎的Unix之父。Unix之父將此符號系統引入編輯器QED,而後是Unix上的編輯器ed,並最終引入grep。Jeffrey Friedl 在其著做《Mastering Regular Expressions (2nd edition)》(中文版譯做:精通正則表達式,已出到第三版)中對此做了進一步闡述講解,若是你但願更多瞭解正則表達式理論和歷史,推薦你看看這本書。
自此之後,正則表達式被普遍地應用到各類UNIX或相似於UNIX的工具中,如你們熟知的Perl。Perl的正則表達式源自於Henry Spencer編寫的regex,以後已演化成了pcre(Perl兼容正則表達式Perl Compatible Regular Expressions),pcre是一個由Philip Hazel開發的、爲不少現代工具所使用的庫。正則表達式的第一個實用應用程序即爲Unix中的 qed 編輯器。
而後,正則表達式在各類計算機語言或各類應用領域獲得了廣大的應用和發展,演變成爲計算機技術森林中的一隻形神美麗且聲音動聽的百靈鳥。
 
以上是關於正則表達式的起源和發展的歷史描述,現在正則表達式在基於文本的編輯器和搜索工具中依然佔據着一個很是重要的地位。
在最近的六十年中,正則表達式逐漸從模糊而深奧的數學概念,發展成爲在計算機各種工具和軟件包應用中的主要功能。不只僅衆多UNIX工具支持正則表達式,近二十年來,在WINDOWS的陣營下,正則表達式的思想和應用在大部分 Windows 開發者工具包中獲得支持和嵌入應用!從正則式在Microsoft Visual Basic 6 或 Microsoft VBScript到.NET Framework中的探索和發展,WINDOWS系列產品對正則表達式的支持發展到無與倫比的高度,幾乎全部 Microsoft 開發者和全部.NET語言均可以使用正則表達式。若是你是一位接觸計算機語言的工做者,那麼你會在主流操做系統(*nix[Linux, Unix等]、Windows、HP、BeOS等)、主流的開發語言(delphi、Scala、PHP、C#、Java、C++、Objective-c、Swift、VB、Javascript、Ruby以及Python等)、數以億萬計的各類應用軟件中,均可以看到正則表達式優美的舞姿。

 

引擎

正則引擎主要能夠分爲兩大類:一種是 DFA,一種是NFA。這兩種引擎都有了好久的歷史(至今二十多年),當中也由這兩種引擎產生了不少變體!
因而POSIX的出臺規避了沒必要要變體的繼續產生。這樣一來,主流的正則引擎又分爲3類:
1、 DFA
2、傳統型NFA,
3、POSIX NFA。
 
DFA 引擎在線性時狀態下執行,由於它們不要求回溯(並所以它們永遠不測試相同的字符兩次)。DFA 引擎還能夠確保匹配最長的可能的字符串。可是,
由於 DFA 引擎 只包含有限的狀態,因此它不能匹配具備反向引用的模式;
由於它不構造顯示擴展,因此它不能夠捕獲子表達式。
 
傳統的 NFA 引擎運行所謂的「貪婪的」匹配回溯算法,以指定順序測試正則表達式的全部可能的擴展並接受第一個匹配項。
由於傳統的 NFA 構造正則表達式的特定擴展以得到成功的匹配,因此它能夠捕獲子表達式匹配和匹配的反向引用。
可是,由於傳統的 NFA 回溯,因此它能夠訪問徹底相同的狀態屢次(若是經過不一樣的路徑到達該狀態)。
所以,在最壞狀況下,它的執行速度可能很是慢。由於傳統的 NFA 接受它找到的第一個匹配,因此它還可能會致使其餘(可能更長)匹配未被發現。
 
POSIX NFA 引擎與傳統的 NFA 引擎相似,不一樣的一點在於:在它們能夠確保已找到了可能的最長的匹配以前,它們將繼續回溯。所以,POSIX NFA 引擎的速度慢於傳統的 NFA 引擎;而且在使用 POSIX NFA 時,您恐怕不會願意在更改回溯搜索的順序的狀況下來支持較短的匹配搜索,而非較長的匹配搜索。
 
使用 DFA引擎的程序主要有: awk,egrep,flex,lex,MySQL,Procmail等;
使用傳統型NFA引擎的程序主要有:GNU Emacs,Java,ergp,less,more,.NET語言,PCRE library,Perl,PHP,Python,Ruby,sed,vi;
使用POSIX NFA引擎的程序主要有:mawk,Mortice Kern Systems’ utilities,GNU Emacs(使用時能夠明確指定);
也有使用DFA/NFA混合的引擎:GNU awk,GNU grep/egrep,Tcl。
 
AWK是一種優良的文本處理工具。它不只是 Linux 中也是任何環境中現有的 功能最強大的數據處理引擎之一。這種編程及數據操做語言(其名稱得自於它的創始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首個字母)的最大功能取決於一我的所擁有的知識。AWK 提供了極其強大的功能:能夠進行樣式裝入、流控制、數學運算符、進程控制語句甚至於內置的變量和函數。它具有了一個完整的語言所應具備的幾乎全部精美特性。實際上 AWK 的確擁有本身的語言:AWK 程序設計語言, 三位建立者已將它正式定義爲「樣式掃描和處理語言」。它容許您建立簡短的程序,這些程序讀取輸入文件、爲數據排序、處理數據、對輸入執行計算以及生成報表,還有無數其餘的功能。
最簡單地說, AWK 是一種用於處理文本的編程語言工具。AWK 在不少方面相似於 shell 編程語言,儘管 AWK 具備徹底屬於其自己的語法
 
舉例簡單說明NFA與DFA工做的區別:
好比有字符串  this is yansen’s blog,正則表達式爲 /ya(msen|nsen|nsem)/ (不要在意表達式怎麼樣,這裏只是爲了說明引擎間的工做區別)。
NFA工做方式以下,先在字符串中查找 y 而後匹配其後是否爲 a ,
若是是,則繼續,查找其後是否爲 m
若是否,則匹配其後是否爲 n (此時淘汰msen選擇支)。
而後繼續看其後是否依次爲 s,e,接着測試是否爲 n ,是 n 則匹配成功,不是則測試是否爲 m 。
 
爲何是 m ?由於 NFA 工做方式是以正則表達式爲標準,反覆測試字符串,這樣一樣一個字符串有可能被反覆測試了不少次!
 
而DFA則不是如此,DFA會從 this 中 t 開始依次查找 y,定位到 y ,已知其後爲 a ,則查看錶達式是否有 a ,此處正好有 a 。而後字符串 a 後爲 n ,DFA依次測試表達式,此時 msen 不符合要求淘汰。
nsen 和 nsem 符合要求,而後DFA依次檢查字符串,檢測到sen 中的 n 時只有nsen 分支符合,則匹配成功!
 
由此能夠看出來,兩種引擎的工做方式徹底不一樣,一個(NFA)以表達式爲主導, 一個(DFA)以文本爲主導
通常而論,DFA引擎則搜索更快一些!可是NFA 以表達式爲主導,反而更容易操縱,所以通常程序員更偏心NFA引擎! 兩種引擎各有所長,而真正的引用則取決與你的須要以及所使用的語言!

 

這裏只簡單瞧瞧 DFA (Deterministic Finite Automata),"肯定有限狀態自動機"。

 

b*a*b*a*b* 有循環,可見是個環。

 

Duality: RE與DFA的等價性

 

侷限性:

Which languages CANNOT be described by any RE?
• Set of all bit strings with equal number of 0s and 1s.  // 沒有計數相關功能
• Set of all decimal strings that represent prime numbers. // 又不是人工智能,:p

 

ab*a

可見,b有環。

a(a|b)*a

可見,(a|b)有環。思考環的構造,以下:

 

 

DFA to RE: State Elimination

• Eliminates states of the automaton and replaces the edges with regular expressions that includes the behavior of the eliminated states.
• Eventually we get down to the situation with just a start and final node, and this is easy to express as a RE

 

We can describe this automaton as: (R | SU*T)*SU*

分析:

對於第一個node來講,有兩條路徑:

    1. R自循環
    2. SU*T繞一圈後再回來

而後考慮end node:也是兩條路徑:

    1. U自循環
    2. 「SU*T繞一圈後再回來」+S

因而便構成了: (R | SU*T)*SU*

 

We can describe this automaton as simply R*

 

標準的elimination過程

Example One:

1) First convert the edges to RE’s.

注意:簡化的過程當中不要丟失信息

2) 有個環,精簡它。

3) 3-->1-->2的過程不能丟失,因此保留"11"。 

Answer: (0+10)*11(0+1)* 

 

Example Two:

1) First convert the edges to RE’s.

注意:簡化的過程當中不要丟失信息

2) 有個環,精簡它。

3) 1-->2-->3的過程不能丟失,因此保留"10*1"。 

注意:這裏有兩個end node

策略:關掉node 1,計算;再關掉node 2,計算。

關掉node 3:

0*

關掉node 1:

0*10*1(0|10*1)*

合併結果(或操做):

0* | 0*10*1(0|10*1)*

相關文章
相關標籤/搜索