This file is indexed.

/usr/share/doc/diveintopython-zh/html/regular_expressions/street_addresses.html is in diveintopython-zh 5.4b-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<!DOCTYPE html
  PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   
      <title>7.2.&nbsp;个案研究:街道地址</title>
      <link rel="stylesheet" href="../diveintopython.css" type="text/css">
      <link rev="made" href="mailto:f8dy@diveintopython.org">
      <meta name="generator" content="DocBook XSL Stylesheets V1.52.2">
      <meta name="keywords" content="Python, Dive Into Python, tutorial, object-oriented, programming, documentation, book, free">
      <meta name="description" content="Python from novice to pro">
      <link rel="home" href="../toc/index.html" title="Dive Into Python">
      <link rel="up" href="index.html" title="第&nbsp;7&nbsp;章&nbsp;正则表达式">
      <link rel="previous" href="index.html" title="第&nbsp;7&nbsp;章&nbsp;正则表达式">
      <link rel="next" href="roman_numerals.html" title="7.3.&nbsp;个案研究:罗马字母">
   </head>
   <body>
      <table id="Header" width="100%" border="0" cellpadding="0" cellspacing="0" summary="">
         <tr>
            <td id="breadcrumb" colspan="5" align="left" valign="top">导航:<a href="../index.html">起始页</a>&nbsp;&gt;&nbsp;<a href="../toc/index.html">Dive Into Python</a>&nbsp;&gt;&nbsp;<a href="index.html">正则表达式</a>&nbsp;&gt;&nbsp;<span class="thispage">个案研究:街道地址</span></td>
            <td id="navigation" align="right" valign="top">&nbsp;&nbsp;&nbsp;<a href="index.html" title="上一页: “正则表达式”">&lt;&lt;</a>&nbsp;&nbsp;&nbsp;<a href="roman_numerals.html" title="下一页: “个案研究:罗马字母”">&gt;&gt;</a></td>
         </tr>
         <tr>
            <td colspan="3" id="logocontainer">
               <h1 id="logo"><a href="../index.html" accesskey="1">深入 Python :Dive Into Python 中文版</a></h1>
               <p id="tagline">Python 从新手到专家 [Dip_5.4b_CPyUG_Release]</p>
            </td>
            <td colspan="3" align="right">
               <form id="search" method="GET" action="http://www.google.com/custom">
                  <p><label for="q" accesskey="4">Find:&nbsp;</label><input type="text" id="q" name="q" size="20" maxlength="255" value=""> <input type="submit" value="搜索"><input type="hidden" name="domains" value="woodpecker.org.cn"><input type="hidden" name="sitesearch" value="www.woodpecker.org.cn/diveintopython"></p>
               </form>
            </td>
         </tr>
      </table>
      <!--#include virtual="/inc/ads" -->
      <div class="section" lang="zh_cn">
         <div class="titlepage">
            <div>
               <div>
                  <h2 class="title"><a name="re.matching"></a>7.2.&nbsp;个案研究:街道地址
                  </h2>
               </div>
            </div>
            <div></div>
         </div>
         <div class="abstract">
            <p>这一系列的例子是由我几年前日常工作中的现实问题启发而来的,当时我需要从一个老化系统中导出街道地址,在将它们导入新的系统之前,进行清理和标准化。(看,我不是只将这些东西堆到一起,它有实际的用处。)这个例子展示我如何处理这个问题。</p>
         </div>
         <div class="example"><a name="d0e17093"></a><h3 class="title">&nbsp;7.1.&nbsp;在字符串的结尾匹配</h3><pre class="screen">
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">s = <span class='pystring'>'100 NORTH MAIN ROAD'</span></span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">s.replace(<span class='pystring'>'ROAD'</span>, <span class='pystring'>'RD.'</span>)</span>               <a name="re.matching.1.1"></a><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12">
<span class="computeroutput">'100 NORTH MAIN RD.'</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">s = <span class='pystring'>'100 NORTH BROAD ROAD'</span></span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">s.replace(<span class='pystring'>'ROAD'</span>, <span class='pystring'>'RD.'</span>)</span>               <a name="re.matching.1.2"></a><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12">
<span class="computeroutput">'100 NORTH BRD. RD.'</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">s[:-4] + s[-4:].replace(<span class='pystring'>'ROAD'</span>, <span class='pystring'>'RD.'</span>)</span> <a name="re.matching.1.3"></a><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12">
<span class="computeroutput">'100 NORTH BROAD RD.'</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput"><span class='pykeyword'>import</span> re</span>                              <a name="re.matching.1.4"></a><img src="../images/callouts/4.png" alt="4" border="0" width="12" height="12">
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">re.sub(<span class='pystring'>'ROAD$'</span>, <span class='pystring'>'RD.'</span>, s)</span>              <a name="re.matching.1.5"></a><img src="../images/callouts/5.png" alt="5" border="0" width="12" height="12"> <a name="re.matching.1.6"></a><img src="../images/callouts/6.png" alt="6" border="0" width="12" height="12">
<span class="computeroutput">'100 NORTH BROAD RD.'</span></pre><div class="calloutlist">
               <table border="0" summary="Callout list">
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#re.matching.1.1"><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">我的目标是将街道地址标准化,<tt class="literal">'ROAD'</tt> 通常被略写为 <tt class="literal">'RD.'</tt>。乍看起来,我以为这个太简单了,只用字符串的方法 <tt class="function">replace</tt> 就可以了。毕竟,所有的数据都已经是大写的了,因此大小写不匹配将不是问题。并且,要搜索的串<tt class="literal">'ROAD'</tt>是一个常量,在这个迷惑的简单例子中,<tt class="function">s.replace</tt> 的确能够胜任。
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#re.matching.1.2"><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">不幸的是,生活充满了特例,并且我很快就意识到这个问题。比如:<tt class="literal">'ROAD'</tt> 在地址中出现两次,一次是作为街道名称 <tt class="literal">'BROAD'</tt> 的一部分,一次是作为 <tt class="literal">'ROAD'</tt> 本身。<tt class="function">replace</tt> 方法遇到这两处的<tt class="literal">'ROAD'</tt>并没有区别,因此都进行了替换,而我发现地址被破坏掉了。
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#re.matching.1.3"><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">为了解决在地址中出现多次<tt class="literal">'ROAD'</tt>子串的问题,有可能采用类似这样的方法:只在地址的最后四个字符中搜索替换 <tt class="literal">'ROAD'</tt> (s[-4:]),忽略字符串的其他部分 (s[:-4])。但是,你可能发现这已经变得不方便了。例如,该模式依赖于你要替换的字符串的长度了 (如果你要把 <tt class="literal">'STREET'</tt> 替换为 <tt class="literal">'ST.'</tt>,你需要利用 <tt class="literal">s[:-6]</tt><tt class="literal">s[-6:].replace(...)</tt>)。你愿意在六月个期间回来调试它们么?我本人是不愿意的。
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#re.matching.1.4"><img src="../images/callouts/4.png" alt="4" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">是时候转到正则表达式了。在 <span class="application">Python</span> 中,所有和正则表达式相关的功能都包含在 <tt class="filename">re</tt> 模块中。
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#re.matching.1.5"><img src="../images/callouts/5.png" alt="5" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">来看第一个参数:<tt class="literal">'ROAD$'</tt>。这个正则表达式非常简单,只有当 <tt class="literal">'ROAD'</tt> 出现在一个字符串的尾部时才会匹配。字符<tt class="literal">$</tt>表示“字符串的末尾”(还有一个对应的字符,尖号<tt class="literal">^</tt>,表示“字符串的开始”)。
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#re.matching.1.6"><img src="../images/callouts/6.png" alt="6" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">利用 <tt class="function">re.sub</tt> 函数,对字符串 <tt class="varname">s</tt> 进行搜索,满足正则表达式 <tt class="literal">'ROAD$'</tt> 的用 <tt class="literal">'RD.'</tt> 替换。这样将匹配字符串 <tt class="varname">s</tt> 末尾的 <tt class="literal">'ROAD'</tt>,而不会匹配属于单词 <tt class="literal">'ROAD'</tt> 一部分的 <tt class="literal">'ROAD'</tt>,这是因为它是出现在 <tt class="varname">s</tt> 的中间。
                     </td>
                  </tr>
               </table>
            </div>
         </div>
         <p>继续我的清理地址的故事。很快我发现,在上面的例子中,仅仅匹配地址末尾的 <tt class="literal">'ROAD'</tt> 不是很好,因为不是所有的地址都包括表示街道的单词 (<tt class="literal">'ROAD'</tt>);有一些直接以街道名结尾。大部分情况下,不会遇到这种情况,但是,如果街道名称为 <tt class="literal">'BROAD'</tt>,那么正则表达式将会匹配 <tt class="literal">'BROAD'</tt> 的一部分为 <tt class="literal">'ROAD'</tt>,而这并不是我想要的。
         </p>
         <div class="example"><a name="d0e17285"></a><h3 class="title">&nbsp;7.2.&nbsp;匹配整个单词</h3><pre class="screen">
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">s = <span class='pystring'>'100 BROAD'</span></span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">re.sub(<span class='pystring'>'ROAD$'</span>, <span class='pystring'>'RD.'</span>, s)</span>
<span class="computeroutput">'100 BRD.'</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">re.sub(<span class='pystring'>'\\bROAD$'</span>, <span class='pystring'>'RD.'</span>, s)</span>  <a name="re.matching.2.2"></a><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12">
<span class="computeroutput">'100 BROAD'</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">re.sub(r<span class='pystring'>'\bROAD$'</span>, <span class='pystring'>'RD.'</span>, s)</span>  <a name="re.matching.2.3"></a><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12">
<span class="computeroutput">'100 BROAD'</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">s = <span class='pystring'>'100 BROAD ROAD APT. 3'</span></span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">re.sub(r<span class='pystring'>'\bROAD$'</span>, <span class='pystring'>'RD.'</span>, s)</span>  <a name="re.matching.2.4"></a><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12">
<span class="computeroutput">'100 BROAD ROAD APT. 3'</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">re.sub(r<span class='pystring'>'\bROAD\b'</span>, <span class='pystring'>'RD.'</span>, s)</span> <a name="re.matching.2.5"></a><img src="../images/callouts/4.png" alt="4" border="0" width="12" height="12">
<span class="computeroutput">'100 BROAD RD. APT 3'</span></pre><div class="calloutlist">
               <table border="0" summary="Callout list">
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#re.matching.2.2"><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">我真正想要做的是,当 <tt class="literal">'ROAD'</tt> 出现在字符串的末尾,并且是作为一个独立的单词时,而不是一些长单词的一部分,才对他进行匹配。为了在正则表达式中表达这个意思,你利用 <tt class="literal">\b</tt>,它的含义是“单词的边界必须在这里”。在 <span class="application">Python</span> 中,由于字符 <tt class="literal">'\'</tt> 在一个字符串中必须转义,这会变得非常麻烦。有时候,这类问题被称为“反斜线灾难”,这也是 <span class="application">Perl</span> 中正则表达式比 <span class="application">Python</span> 的正则表达式要相对容易的原因之一。另一方面,<span class="application">Perl</span> 也混淆了正则表达式和其他语法,因此,如果你发现一个 bug,很难弄清楚究竟是一个语法错误,还是一个正则表达式错误。
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#re.matching.2.3"><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">为了避免反斜线灾难,你可以利用所谓的“原始字符串”,只要为字符串添加一个前缀 <tt class="literal">r</tt> 就可以了。这将告诉 <span class="application">Python</span>,字符串中的所有字符都不转义;<tt class="literal">'\t'</tt> 是一个制表符,而 <tt class="literal">r'\t'</tt> 是一个真正的反斜线字符 <tt class="literal">'\'</tt>,紧跟着一个字母 <tt class="literal">'t'</tt>。我推荐只要处理正则表达式,就使用原始字符串;否则,事情会很快变得混乱 (并且正则表达式自己也会很快被自己搞乱了)。
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#re.matching.2.4"><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">(一声叹息) 很不幸,我很快发现更多的与我的逻辑相矛盾的例子。在这个例子中,街道地址包含有作为整个单词的<tt class="literal">'ROAD'</tt>,但是它不是在末尾,因为地址在街道命名后会有一个房间号。由于 <tt class="literal">'ROAD'</tt> 不是在每一个字符串的末尾,没有匹配上,因此调用 <tt class="function">re.sub</tt> 没有替换任何东西,你获得的只是初始字符串,这也不是我们想要的。
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#re.matching.2.5"><img src="../images/callouts/4.png" alt="4" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">为了解决这个问题,我去掉了 <tt class="literal">$</tt> 字符,加上另一个 <tt class="literal">\b</tt>。现在,正则表达式“<span class="quote">匹配字符串中作为整个单词出现的<tt class="literal">'ROAD'</tt></span>”了,不论是在末尾、开始还是中间。
                     </td>
                  </tr>
               </table>
            </div>
         </div>
      </div>
      <table class="Footer" width="100%" border="0" cellpadding="0" cellspacing="0" summary="">
         <tr>
            <td width="35%" align="left"><br><a class="NavigationArrow" href="index.html">&lt;&lt;&nbsp;正则表达式</a></td>
            <td width="30%" align="center"><br>&nbsp;<span class="divider">|</span>&nbsp;<a href="index.html#re.intro" title="7.1.&nbsp;概览">1</a> <span class="divider">|</span> <span class="thispage">2</span> <span class="divider">|</span> <a href="roman_numerals.html" title="7.3.&nbsp;个案研究:罗马字母">3</a> <span class="divider">|</span> <a href="n_m_syntax.html" title="7.4.&nbsp;使用 {n,m} 语法">4</a> <span class="divider">|</span> <a href="verbose.html" title="7.5.&nbsp;松散正则表达式">5</a> <span class="divider">|</span> <a href="phone_numbers.html" title="7.6.&nbsp;个案研究:解析电话号码">6</a> <span class="divider">|</span> <a href="summary.html" title="7.7.&nbsp;小结">7</a>&nbsp;<span class="divider">|</span>&nbsp;
            </td>
            <td width="35%" align="right"><br><a class="NavigationArrow" href="roman_numerals.html">个案研究:罗马字母&nbsp;&gt;&gt;</a></td>
         </tr>
         <tr>
            <td colspan="3"><br></td>
         </tr>
      </table>
      <div class="Footer">
         <p class="copyright">Copyright © 2000, 2001, 2002, 2003, 2004 <a href="mailto:mark@diveintopython.org">Mark Pilgrim</a></p>
         <p class="copyright">Copyright © 2001, 2002, 2003, 2004, 2005, 2006, 2007 <a href="mailto:python-cn@googlegroups.com">CPyUG (邮件列表)</a></p>
      </div>
   </body>
</html>