[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)*

相关文章
相关标签/搜索