正则表达式和文本挖掘(Text Mining)

Bloom123 8年前
   <p>在进行文本挖掘时,TSQL中的通配符(Wildchar)显得功能不足,这时,使用“CLR+正则表达式”是非常不错的选择,正则表达式看似非常复杂,但,万变不离其宗,熟练掌握正则表达式的元数据,就能熟练和灵活使用正则表达式完成复杂的Text Mining工作。</p>    <h3><strong>一,正则表达式的特殊字符</strong></h3>    <p><strong>1,常用元字符</strong></p>    <p>用以匹配特定的字符(字母,数字,符号),注意字母是区分大小写的:</p>    <ul>     <li> <p><strong>.</strong> :匹配除换行符以外的任意字符</p> </li>     <li> <p><strong>\w</strong> :匹配字母或数字或下划线或汉字</p> </li>     <li> <p><strong>\s</strong> :匹配任意的空白符</p> </li>     <li> <p><strong>\d</strong> :匹配数字</p> </li>     <li> <p><strong>\b</strong> :匹配单词的开始或结束</p> </li>     <li> <p><strong>^</strong> :匹配字符串的开始</p> </li>     <li> <p><strong>$</strong> :匹配字符串的结束</p> </li>     <li> <p><strong>\k : </strong> 引用 分组名,例如:\k<group_name>,表示引用名字为group_name的分组</p> </li>     <li> <p><strong>\group_number: </strong> group_number是分组的组号,1,2,3等,表示通过组号引用分组</p> </li>    </ul>    <p><strong>2,重复字符或分组</strong></p>    <p>指定前面一个字符或分组重复的次数:</p>    <ul>     <li> <p><strong>*</strong> :重复零次或更多次</p> </li>     <li> <p><strong>+</strong> :重复一次或更多次</p> </li>     <li> <p><strong>?</strong> :重复零次或一次</p> </li>     <li> <p><strong>{n}</strong> :重复n次</p> </li>     <li> <p><strong>{n,}</strong> :重复n次或更多次</p> </li>     <li> <p><strong>{n,m}</strong> :重复n到m次</p> </li>    </ul>    <p><strong>3,分组,转义,分支,限定符</strong></p>    <p>这些字符有特定的含义和用途:</p>    <ul>     <li> <p><strong>()</strong> : 用小括号表示一个分组</p> </li>     <li> <p><strong><></strong> : 定义分组名< 和 > 之间的字符串是分组名</p> </li>     <li> <p><strong>\</strong> : 转义字符,将特殊字符转移为普通字符,例如:\(,表示小括号“(”,小括号不再作为特殊字符</p> </li>     <li> <p><strong>|</strong> : 分支,表达式之间是“或”的关系</p> </li>     <li> <p><strong>[]</strong> : 指定限定字符列表,一个字符必须匹配列表中任意一个字符,在中括号中指定匹配的字符列表,例如:[aeiou] 一个字符必须aeiou中的任意一个;</p> </li>     <li> <p><strong>[^ ]</strong> : 指定排除字符列表,一个字符不能是排除列表中的任意一个字符,中括号中指定排除的字符列表,例如:[^aeiou] 一个字符不能是aeiou中的任意一个;</p> </li>    </ul>    <h3><strong>二,分组引用</strong></h3>    <p>分组,是使用小括号指定的一个子表达式; 分组引用,是指在表达式中,重复使用子表达式,使正则表达式的写法更简洁。默认情况下,正则表达式为每个分组自动分配一个 组号,规则是:组号从1开始,从左向右,组号依次加1(base-1),例如,第一个分组的组号为1,第二个分组的组号为2,以此类推。</p>    <p><strong>分组定义的三种形式:</strong></p>    <ul>     <li> <p><strong>(exp)</strong> :自动分配组号,通过分组号引用该分组;</p> </li>     <li> <p><strong>(?<name>exp)</strong> :命名分组,通过分组名引用该分组;</p> </li>     <li> <p><strong>(?:exp)</strong> :该分组只在当前位置匹配文本,在该分组之后,无法引用该分组,该分组没有分组名,也没有分组号;</p> </li>    </ul>    <p><strong>1,通过组号引用分组</strong></p>    <p>在正则表达式前面定义一个分组(exp),在表达式的后面,能够通过组号引用该分组的表达式,引用分组的语法是:\group_number;</p>    <p>例如: <strong>\b(\w+)\b\s+\1\b</strong> ,在该正则表达式中,只存在一个分组(\w+),组号是1,在该分组的后面,使用\1来引用该分组,将\1替换为分组的子表达式,等价于: <strong>\b(\w+)\b\s+(\w+)\b</strong> 。</p>    <p><strong>2,通过分组名引用分组</strong></p>    <p>在正则表达式中,能够对分组命名,命名的分组格式:(?<name>exp),分组名是name,通过name来引用该分组的格式是:\k<group_name>,通过分组名和组号引用分组,其文本匹配的行为是一样的。</p>    <p>例如: <strong>\b(?<word>\w+)\b\s+\1\b</strong> ,在该分组的后面中,使用 \k<word> 引用该分组,将 \k<word> 替换为分组的子表达式,等价于: <strong>\b(\w+)\b\s+(\w+)\b</strong> 。</p>    <p><strong>3,无法引用的分组</strong></p>    <p>(?:exp):使用这种语法定义的分组,不能引用,只能在当前的位置匹配文本,正则表达式不为该分组自动分配组号。</p>    <h3><strong>三,断言查找</strong></h3>    <p>断言是一个逻辑表达式,只有当表达式为真时,匹配成功。当匹配成功时,返回文本,返回的文本不包含前缀或后缀,即,断言用于查找在特定“文本”之前或之后的文本。断言的四种语法:</p>    <ul>     <li> <p><strong>(?=exp)</strong> :文本的后面匹配表达式exp,返回exp位置之前的表达式</p> </li>     <li> <p><strong>(?<=exp)</strong> :文本的前面匹配表达式exp,返回exp位置之后的表达式</p> </li>     <li> <p><strong>(?!exp)</strong> :文本的后缀不是exp,返回后缀 不是exp的 表达式</p> </li>     <li> <p><strong>(?<!exp)</strong> :文本的前缀不是exp,返回前缀 不是exp的 表达式</p> </li>    </ul>    <p><strong>1,后缀匹配</strong></p>    <p>(?=exp):文本的后面匹配表达式exp,返回exp位置之前的表达式。后缀匹配,和TSQL的 "%ing"类似;</p>    <p>比如正则表达式: <strong>\b\w+(?=ing\b)</strong></p>    <p>分析:断言其后缀是ing,并且是单词的结尾(\b),匹配以ing结尾的单词,但返回单词的前面部分,ing之前的部分;</p>    <p>例如,查找“I'm reading a book”,它会匹配“reading”,因为该字符后面以ing结尾,该正则表达式返回read,断言返回的文本不包含后缀。</p>    <p><strong>2,前缀匹配</strong></p>    <p>(?<=exp):文本的前面匹配表达式exp,返回exp位置之后的表达式。前缀匹配,和TSQL的 "re%"类似;</p>    <p>比如正则表达式:</p>    <p>(?<=\bre)\w+\b</p>    <p>分析:单词的打头(\b),并且单词的前缀是re,匹配以re开头的单词,返回单词的后半部分,re之后的部分;</p>    <p>例如,查找“I am reading a book”,它会匹配“reading”,因为该字符前面以re打头,该正则表达式返回ading,断言返回的文本不包含前缀。</p>    <p><strong>3,查找前缀或后缀不是特定文本的文本</strong></p>    <p>这两个断言查找,跟前面两个相反,作用不大,简单了解一下:</p>    <ul>     <li><strong>(?!exp)</strong> <strong> </strong> :文本的后缀不是exp,返回后缀 不是exp的表达式</li>     <li><strong>(?<!exp)</strong> <strong> </strong> :文本的前缀不是exp,返回前缀 不是exp的表达式</li>    </ul>    <p>3.1 比如,正则表达式: <strong>\b</strong> <strong> \w+ <strong>(?!ing\b)</strong> </strong></p>    <p>分析:不匹配以ing结尾的单词,查找“I am reading a book”,返回的文本:I,am,a,book</p>    <p>3.2 比如,正则表达式: <strong> (?<!\bre)\w+\b </strong></p>    <p>分析:不匹配以re打头的单词,查找“I am reading a book”,返回的文本:I,am,a,book</p>    <p> </p>    <p>来自:http://www.cnblogs.com/ljhdo/p/4847209.html</p>    <p> </p>