2017-07-08 00:47:35 vonuo 阅读数 14805
  • Python-数据

    Python数据库编程视频教程,数据库是MySQL,讲解Python链接MySQL数据库,并对数据库进行增删改查操作。

    10902 人正在学习 去看看 尹成

GDAL是空间数据处理的开源包,支持多种数据格式的读写。遥感图像是一种带大地坐标的栅格数据,遥感图像的栅格模型包含以下两部分的内容:

栅格矩阵:由正方形或者矩形栅格点组成,每个栅格点所对应的数值为该点的像元值,在遥感图像中用于表示地物属性值;遥感图像有单波段与多波段,波段表示地物属性的种类,每个波段表示地物一种属性。

大地坐标空间数据参考表示地图的投影信息;仿射矩阵能将行列坐标映射到面坐标上。

GDAL读写遥感数据的代码:

from osgeo import gdal
import os

class GRID:

    #读图像文件
    def read_img(self,filename):
        dataset=gdal.Open(filename)       #打开文件

        im_width = dataset.RasterXSize    #栅格矩阵的列数
        im_height = dataset.RasterYSize   #栅格矩阵的行数

        im_geotrans = dataset.GetGeoTransform()  #仿射矩阵
        im_proj = dataset.GetProjection() #地图投影信息
        im_data = dataset.ReadAsArray(0,0,im_width,im_height) #将数据写成数组,对应栅格矩阵

        del dataset 
        return im_proj,im_geotrans,im_data

    #写文件,以写成tif为例
    def write_img(self,filename,im_proj,im_geotrans,im_data):
        #gdal数据类型包括
        #gdal.GDT_Byte, 
        #gdal .GDT_UInt16, gdal.GDT_Int16, gdal.GDT_UInt32, gdal.GDT_Int32,
        #gdal.GDT_Float32, gdal.GDT_Float64

        #判断栅格数据的数据类型
        if 'int8' in im_data.dtype.name:
            datatype = gdal.GDT_Byte
        elif 'int16' in im_data.dtype.name:
            datatype = gdal.GDT_UInt16
        else:
            datatype = gdal.GDT_Float32

        #判读数组维数
        if len(im_data.shape) == 3:
            im_bands, im_height, im_width = im_data.shape
        else:
            im_bands, (im_height, im_width) = 1,im_data.shape 

        #创建文件
        driver = gdal.GetDriverByName("GTiff")            #数据类型必须有,因为要计算需要多大内存空间
        dataset = driver.Create(filename, im_width, im_height, im_bands, datatype)

        dataset.SetGeoTransform(im_geotrans)              #写入仿射变换参数
        dataset.SetProjection(im_proj)                    #写入投影

        if im_bands == 1:
            dataset.GetRasterBand(1).WriteArray(im_data)  #写入数组数据
        else:
            for i in range(im_bands):
                dataset.GetRasterBand(i+1).WriteArray(im_data[i])

        del dataset

if __name__ == "__main__":
    os.chdir(r'D:\Python_Practice')                        #切换路径到待处理图像所在文件夹
    run = GRID()
    proj,geotrans,data = run.read_img('LC81230402013164LGN00.tif')        #读数据
    print proj
    print geotrans
    print data
    print data.shape
    run.write_img('LC81230402013164LGN00_Rewrite.tif',proj,geotrans,data) #写数据

在GDAL遥感影像读写的基础上,我们可以进行遥感图像的各种公式计算和统计分析。
例如我们所熟知的计算NDVI(归一化植被指数),只要在以上代码倒数第二行中插入代码:

import numpy as np
data = data.astype(np.float)
ndvi = (data[3]-data[2])/(data[3]+data[2])                         #3为近红外波段;2为红波段
run.write_img('LC81230402013164LGN00_ndvi.tif',proj,geotrans,ndvi) #写为ndvi图像

当然,这是理想的NDVI,实际处理NDVI还会遇到一些其他要处理的问题。例如NDVI值应该在区间[-1,1]内,但实际中会出现大于1或小于-1的情况,或者某些像点是坏点,出现空值nan,需要进一步的配套处理。

2017-05-02 08:09:00 weixin_34119545 阅读数 11
  • Python-数据

    Python数据库编程视频教程,数据库是MySQL,讲解Python链接MySQL数据库,并对数据库进行增删改查操作。

    10902 人正在学习 去看看 尹成

本节书摘来自异步社区《Python地理数据处理》一书中的第1章,第1.3节,作者: 【美】Chris Garrard(加勒德) 更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.3 地理数据处理

地理数据处理是处理空间数据的总称,不管处理的是栅格数据,还是矢量数据。可以想象一下,地理数据处理的覆盖面相当广泛。我一直认为,使用GIS的地理数据处理工具就像做数据统计一样,几乎可以应用于所有事情中,甚至在日常生活中也会用到地理数据处理,不管你是否意识到这一点。例如,我会根据是开车还是骑自行车来选取不同的出行路线,当我骑自行车上班时,我会选择避开没有护栏的高流量道路。对于有陡峭山坡的路线,开车时我不会顾虑太多,但骑自行车时就会比较关心。像这种基于上班所做的路线选择,不仅考虑到道路方向、高程等空间因素,还有交通流量和道路宽度等属性,这就是一种地理数据处理,可能你每天都在做类似的决定。

除了简单的选择一条上班路线,你有很多理由对地理数据处理产生兴趣。让我们看几个相关的应用实例。早期空间分析比较著名的例子是John Snow的故事,他是一位生活在19世纪初的英国医生。虽然故事的部分内容一直存在争议,但故事的要点是,他使用空间分析的方法确定了1854年爆发的霍乱疫情的形成原因。他绘制的地图一角已经在图1.6中进行了展示,在地图上布罗德大街上的水泵位于中间。你可以看到许多看起来像条形块的符号被固定在附近的街道上,每一个条形块由一个与道路平行的线条构成,代表一个霍乱受害者。Snow意识到,大多数受害者可能从布罗德大街上的水泵取水,因为这个水泵是离他们最近的一个,于是他说服当局关闭水泵。这个故事非常重要,不仅仅是因为它是早期使用空间分析的案例,还因为当时并不知道霍乱是通过受污染的水进行传染的。正因为如此,John Snow被认为是现代流行病学的奠基人之一。


0c845f38bb450be1f8cb809dcb8ecac4f0c4adca

空间分析目前仍然是流行病学研究的重要组成部分,除此以外,它还被广泛应用于其他领域。我做过的空间分析项目包括:研究濒危物种的生活习性,模拟大面积区域的植被覆盖,比较洪涝前后不同时间的数据查看河道是如何变化的,模拟森林的碳汇。你也许可以在自己感兴趣的领域找到其他空间分析相关的例子。下面再看一些其他的例子。

中国的研究人员骆磊等人使用空间分析的方式,结合历史记录,来查明丝绸之路沿线已经消失的驿站位置。史籍资料记录了有关路线的描述,包括行驶的距离和驿站之间的大致方位。目前几个驿站的位置已经确定,研究者们认为,古代旅客们不太可能沿着一条直线行进,而是会随着河流或者其他地貌前行。他们使用所有这些信息来确定那些仍未发现的驿站的可能地理位置区域,然后再使用高分辨率的卫星影像来搜索可能是驿站遗址的区域几何形状。实地考察后,他们发现其中一个是古代的驿站,另外两个可能是汉朝时期的军事设施。

另一个完全不同的应用领域是,Moody等人着力于研究利用微藻作为生物燃料。他们利用微藻的生长模型和来自世界各地不同地点的气象数据模拟生物的生产能力。由于气象数据只是特定站点的数值,分析的结果使用空间插值的方式绘制出一副全球的生产能力图。图中显示最有潜力的区域位于澳大利亚、巴西、哥伦比亚、埃及、埃塞俄比亚、印度、肯尼亚和沙特阿拉伯。

更有趣的是,空间分析同样影响着人们的日常生活。你是否注意到你的汽车保险费用会根据你所生活的区域而有所不同?同样的空间分析也可能影响着你喜欢的咖啡馆或杂货店的位置。我所在的社区准备建造一些新的小学和中学,在考虑到适宜地块可用性的同时,还要部分考虑未来学生的空间分布情况。

空间分析不仅仅局限于地理方面,Rose等人论证了地理信息系统(Geographic Information System,GIS)可以被用来分析骨骼中纳米结构和微结构的分布情况。他们使用GIS来查看骨骼的重塑事件是如何与承受了高密度压缩和拉伸的骨骼部分相对应的。

你个人可能需要处理一下数据,使其更适合地图的展示,如去除不想要的要素或者化简复杂的线段,以便在网络地图上快速地绘制显示;你可能会分析人口统计数据来规划未来的交通运输需求;也许你对植被是如何响应不同的土地管理方式感兴趣,如指定焚烧或者修建,或者对此完全不感兴趣。

虽然地理数据处理技术有时候相当复杂,但大多都非常简单。在本书中,你会学到一些简单的应用,但它们是其他所有分析的基础。当你大功告成之时,你将学会读写多种格式的空间数据(矢量和栅格)。可以根据矢量数据的属性值或空间位置对其进行裁剪。你将学会如何进行叠加分析和邻近分析等简单的矢量地理数据处理。此外,你会知道如何处理栅格数据集,包括调整像素、基于多个数据集进行像素计算以及移动窗口分析。

你将学会使用Python来做所有的这一切,而不仅仅是通过单击软件程序中的某些按钮来实现。能够将处理流程写成脚本(这一点)非常强大,不仅可以非常简单地一次批量处理多个数据集(我经常这么做),而且可以让你自定义分析操作,而不是受限于软件的用户界面。你可以根据自己的工作流程自定义工具包,并重复使用。自动化是脚本的另一大优势,这也是我一开始就爱上脚本的原因。我不喜欢单击按钮一遍又一遍地做同样的事情,但我会非常高兴地花时间搞清楚它是如何自动执行的,这样我就不用再想它了。最后一个我要提到的优势是,只要你没把脚本弄丢,总会知道自己做了什么,因为所有的一切都在那里。

2019-09-18 19:38:24 awpc21 阅读数 256
  • Python-数据

    Python数据库编程视频教程,数据库是MySQL,讲解Python链接MySQL数据库,并对数据库进行增删改查操作。

    10902 人正在学习 去看看 尹成

对使用Python的相关职位做一个总结

查找相关资料做了一个整理与汇总

python职业成长路径:

在这里插入图片描述

python职位路径:在这里插入图片描述

Python职业要求:

在这里插入图片描述

岗位要求:

在这里插入图片描述在这里插入图片描述

主要考察点:

业务方向考查:偏向思维商业分析层面

面试考查点:SQL操作、统计知识、业务理解能力逻辑分析能力(有可能采用分组群面的方式)

技术方向:偏向技术数据处理、挖掘层面

面试考察点:SQL、算法、数据清洗、机器学习

互联网行业的相关技术岗位:在这里插入图片描述

数据领域技能

在这里插入图片描述

2018-10-22 12:48:54 Stephen_shijun 阅读数 3792
  • Python-数据

    Python数据库编程视频教程,数据库是MySQL,讲解Python链接MySQL数据库,并对数据库进行增删改查操作。

    10902 人正在学习 去看看 尹成

一直以来,数据可视化就是一个处于不断演变之中的概念,其边界在不断地扩大;因而,最好是对其加以宽泛的定义。数据可视化指的是技术上较为高级的技术方法,而这些技术方法允许利用图形、图像处理、计算机视觉以及用户界面,通过表达、建模以及对立体、表面、属性以及动画的显示,对数据加以可视化解释。与立体建模之类的特殊技术方法相比,数据可视化所涵盖的技术方法要广泛得多。

1.环境

系统:windows10

python版本:python3.6.1

使用的库:matplotlib,numpy

2.numpy库产生随机数几种方法

import numpy as np
numpy.random
rand(d0, d1, ..., dn)

In [2]: x=np.random.rand(2,5)

In [3]: x
Out[3]:
array([[ 0.84286554,  0.50007593,  0.66500549,  0.97387807,  0.03993009],
       [ 0.46391661,  0.50717355,  0.21527461,  0.92692517,  0.2567891 ]])

randn(d0, d1, ..., dn)查询结果为标准正态分布

In [4]: x=np.random.randn(2,5)

In [5]: x
Out[5]:
array([[-0.77195196,  0.26651203, -0.35045793, -0.0210377 ,  0.89749635],
       [-0.20229338,  1.44852833, -0.10858996, -1.65034606, -0.39793635]])

randint(low,high,size)

生成low到high之间(半开区间 [low, high)),size个数据

In [6]: x=np.random.randint(1,8,4)

In [7]: x
Out[7]: array([4, 4, 2, 7])

random_integers(low,high,size)

生成low到high之间(闭区间 [low, high)),size个数据

In [10]: x=np.random.random_integers(2,10,5)

In [11]: x
Out[11]: array([7, 4, 5, 4, 2])

3.散点图

x x轴
y y轴
s   圆点面积
c   颜色
marker  圆点形状
alpha   圆点透明度                #其他图也类似这种配置
N=50
# height=np.random.randint(150,180,20)
# weight=np.random.randint(80,150,20)
x=np.random.randn(N)
y=np.random.randn(N)
plt.scatter(x,y,s=50,c='r',marker='o',alpha=0.5)
plt.show()

4.折线图

x=np.linspace(-10000,10000,100) #将-10到10等区间分成100份
y=x**2+x**3+x**7
plt.plot(x,y)
plt.show()

折线图使用plot函数

5.条形图

N=5
y=[20,10,30,25,15]
y1=np.random.randint(10,50,5)
x=np.random.randint(10,1000,N)
index=np.arange(N)
plt.bar(left=index,height=y,color='red',width=0.3)
plt.bar(left=index+0.3,height=y1,color='black',width=0.3)
plt.show()

orientation设置横向条形图

N=5
y=[20,10,30,25,15]
y1=np.random.randint(10,50,5)
x=np.random.randint(10,1000,N)
index=np.arange(N)
# plt.bar(left=index,height=y,color='red',width=0.3)
# plt.bar(left=index+0.3,height=y1,color='black',width=0.3)
#plt.barh() 加了h就是横向的条形图,不用设置orientation
plt.bar(left=0,bottom=index,width=y,color='red',height=0.5,orientation='horizontal')
plt.show()

6.直方图

m1=100
sigma=20
x=m1+sigma*np.random.randn(2000)
plt.hist(x,bins=50,color="green",normed=True)
plt.show()

# #双变量的直方图
# #颜色越深频率越高
# #研究双变量的联合分布
#双变量的直方图
#颜色越深频率越高
#研究双变量的联合分布
x=np.random.rand(1000)+2
y=np.random.rand(1000)+3
plt.hist2d(x,y,bins=40)
plt.show()

7.饼状图

#设置x,y轴比例为1:1,从而达到一个正的圆
#labels标签参数,x是对应的数据列表,autopct显示每一个区域占的比例,explode突出显示某一块,shadow阴影
labes=['A','B','C','D']
fracs=[15,30,45,10]
explode=[0,0.1,0.05,0]
#设置x,y轴比例为1:1,从而达到一个正的圆
plt.axes(aspect=1)
#labels标签参数,x是对应的数据列表,autopct显示每一个区域占的比例,explode突出显示某一块,shadow阴影
plt.pie(x=fracs,labels=labes,autopct="%.0f%%",explode=explode,shadow=True)
plt.show()

8.箱型图

import matplotlib.pyplot as plt
import numpy as np
data=np.random.normal(loc=0,scale=1,size=1000)
#sym 点的形状,whis虚线的长度
plt.boxplot(data,sym="o",whis=1.5)
plt.show()
#sym 点的形状,whis虚线的长度

2004-11-23 13:08:00 naive1010 阅读数 2271
  • Python-数据

    Python数据库编程视频教程,数据库是MySQL,讲解Python链接MySQL数据库,并对数据库进行增删改查操作。

    10902 人正在学习 去看看 尹成

与其它几种流行的脚本语言一样,Python 是一种用于浏览和处理文本数据的优秀工具。本文为 Python 的初学者概述了 Python 的文本处理工具。文章说明了规则表达式的一些常规概念,并提供了处理文本时,什么情况下应使用(或不使用)规则表达式的建议。

什么是 Python?
Python 是由 Guido van Rossum 开发的、可免费获得的、非常高级的解释型语言。其语法简单易懂,而其面向对象的语义功能强大(但又灵活)。Python 可以广泛使用并具有高度的可移植性。

字符串 -- 不可改变的序列
如同大多数高级编程语言一样,变长字符串是 Python 中的基本类型。Python 在“后台”分配内存以保存字符串(或其它值),程序员不必为此操心。Python 还有一些其它高级语言没有的字符串处理功能。

在 Python 中,字符串是“不可改变的序列”。尽管不能“按位置”修改字符串(如字节组),但程序可以引用字符串的元素或子序列,就象使用任何序列一样。Python 使用灵活的“分片”操作来引用子序列,字符片段的格式类似于电子表格中一定范围的行或列。以下交互式会话说明了字符串和字符片段的的用法:

字符串和分片

>>> s = "mary had a little lamb"
>>> s[0] # index is zero-based
'm'
>>> s[3] = 'x' # changing element in-place fails
Traceback (innermost last):
 File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment
>>> s[11:18] # 'slice' a subsequence
'little '
>>> s[:4] # empty slice-begin assumes zero
'mary'
>>> s[4] # index 4 is not included in slice [:4]
' '
>>> s[5:-5] # can use "from end" index with negatives
'had a little'
>>> s[:5]+s[5:] # slice-begin & slice-end are complimentary
'mary had a little lamb'

另一个功能强大的字符串操作就是简单的 in 关键字。它提供了两个直观有效的构造:

in 关键字

>>> s = "mary had a little lamb"
>>> for c in s[11:18]: print c, # print each char in slice
...
l i t t l e
>>> if 'x' in s: print 'got x' # test for char occurrence
...
>>> if 'y' in s: print 'got y' # test for char occurrence
...
got y

在 Python 中,有几种方法可以构成字符串文字。可以使用单引号或双引号,只要左引号和右引号匹配,常用的还有其它引号的变化形式。如果字符串包含换行符或嵌入引号,三重引号可以很方便地定义这样的字符串,如下例所示:

三重引号的使用

>>> s2 = """Mary had a little lamb
... its fleece was white as snow
... and everywhere that Mary went
... the lamb was sure to go"""
>>> print s2
Mary had a little lamb
its fleece was white as snow
and everywhere that Mary went
the lamb was sure to go

使用单引号或三重引号的字符串前面可以加一个字母 "r" 以表示 Python 不应该解释规则表达式特殊字符。例如:

使用 "r-strings"

>>> s3 = "this /n and /n that"
>>> print s3
this
and
that
>>> s4 = r"this /n and /n that"
>>> print s4
this /n and /n that

在 "r-strings" 中,可能另外组成换码符的反斜杠被当作是常规反斜杠。在以后的规则表达式讨论中会进一步说明这个话题。

文件和字符串变量
我们谈到“文本处理”时,我们通常是指处理的内容。Python 将文本文件的内容读入可以操作的字符串变量非常容易。文件对象提供了三个“读”方法: .read().readline().readlines()。每种方法可以接受一个变量以限制每次读取的数据量,但它们通常不使用变量。 .read() 每次读取整个文件,它通常用于将文件内容放到一个字符串变量中。然而 .read() 生成文件内容最直接的字符串表示,但对于连续的面向行的处理,它却是不必要的,并且如果文件大于可用内存,则不可能实现这种处理。

.readline().readlines() 非常相似。它们都在类似于以下的结构中使用:

Python .readlines() 示例

        fh = open('c://autoexec.bat')
for line in fh.readlines():
 print line


.readline().readlines() 之间的差异是后者一次读取整个文件,象 .read() 一样。.readlines() 自动将文件内容分析成一个行的列表,该列表可以由 Python 的 for ... in ... 结构进行处理。另一方面,.readline() 每次只读取一行,通常比 .readlines() 慢得多。仅当没有足够内存可以一次读取整个文件时,才应该使用 .readline()

如果正在使用处理文件的标准模块,可以使用 cStringIO 模块将字符串转换成“虚拟文件”(如果需要生成模块的子类,可以使用 StringIO 模块,初学者未必要这样做)。例如:

cStringIO 模块

>>> import cStringIO
>>> fh = cStringIO.StringIO()
>>> fh.write("mary had a little lamb")
>>> fh.getvalue()
'mary had a little lamb'
>>> fh.seek(5)
>>> fh.write('ATE')
>>> fh.getvalue()
'mary ATE a little lamb'


但是,请记住,cStringIO“虚拟文件”不是永久的,这一点与真正的文件不同。如果不保存它(如将它写入一个真正的文件,或者使用 shelve 模块或数据库),则程序结束时,它将消失。

标准模块:string
string 模块也许是 Python 1.5.* 标准发行版中最常用的模块。实际上,在 Python 1.6 或更高版本中,string 模块中的功能将作为内置字符串方法(在撰写本文时,详细信息尚未发布)。当然,任何执行文本处理任务的程序也许应该用以下这行开头:

开始使用 string 的方法

      import string


一般经验法则告诉我们,如果可以使用 string 模块完成任务,那么那就是正确的方法。与 re(规则表达式)相比,string 函数通常更快速,大多数情况下他们更易于理解和维护。第三方 Python 模块,包括某些用 C 编写的快速模块,适用于专门的任务,但可移植性和熟悉性都建议只要可能就使用 string。如果您习惯于使用其它语言,也会有例外,但不如您想像的那样多。

string 模块包含了几种类型的事物,如函数、方法和类;它还包含了公共常量的字符串。例如:

string 用法例 1

>>> import string
>>> string.whitespace
'/011/012/013/014/015 '
>>> string.uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'


虽然可以用手写出这些常量,string 版本或多或少确保了常量对于运行 Python 脚本的国家语言和平台将是正确的。

string 还包括了以常见方式(可以结合这些方式来构成几种罕见的转换)转换字符串的函数。例如:

string 用法例 2

>>> import string
>>> s = "mary had a little lamb"
>>> string.capwords(s)
'Mary Had A Little Lamb'
>>> string.replace(s, 'little', 'ferocious')
'mary had a ferocious lamb'


还有许多没有在这里具体说明的其它转换;可以在 Python 手册中查找详细信息。

还可以使用 string 函数来报告字符串属性,如子串的长度或位置,例如:

string 用法例 3

>>> import string
>>> s = "mary had a little lamb"
>>> string.find(s, 'had')5>>> string.count(s, 'a')4


最后,string 提供了非常 Python 化的奇特事物。.split().join() 对提供了在字符串和字节组之间转换的迅捷方法,您会发现它们非常有用。用法很简单:

string 用法例 4

>>> import string>>> s = "mary had a little lamb"
>>> L = string.split(s)
>>> L
['mary', 'had', 'a', 'little', 'lamb']
>>> string.join(L, "-")
'mary-had-a-little-lamb'

当然,除了 .join() 之外,也许会利用列表来做其它事(如某些涉及我们熟悉的 for ... in ... 结构的事情)。

标准模块:re
re 模块废弃了在老的 Python 代码中使用的 regexregsub 模块。虽然相对于 regex 仍然有几个有限的优点,不过这些优点微不足道,不值得在新代码中使用。过时的模块可能会从未来的 Python 发行版中删除,并且 1.6 版可能有一个改进的接口兼容的 re 模块。所以,规则表达式仍将使用 re 模块。

规则表达式很复杂。也许有人会撰写关于这个主题的书,但实际上,已经有许多人这样做了!本文尝试捕捉规则表达式的“完全形态”,让读者可以掌握它。

规则表达式是一种很简练方法,用于描述可能在文本中出现的模式。是否会出现某些字符?是否按特定顺序出现?子模式是否会重复一定次数?其它子模式是否会排除在匹配之外?从概念上说,似乎不能用自然语言了直观地描述模式。诀窍是使用规则表达式的简洁语法来编码这种描述。

当处理规则表达式时,将它作为它自己的编程问题来处理,即使只涉及一或两行代码;这些行有效地构成了一个小程序。

从最小处着手。从最基本上看,任何规则表达式都涉及匹配特定的“字符类”。最简单的字符类就是单个字符,它在模式中只是一个字。通常,您希望匹配一类字符。可以通过将类括在方括号内来表明这是一个类;在括号中,可以有一组字符或者用破折号指定的字符范围。还可以使用许多命名字符类来确定您的平台和国家语言。以下是一些示例:

字符类

>>> import re
>>> s = "mary had a little lamb"
>>> if re.search("m", s): print "Match!" # char literal
Match!
>>> if re.search("[@A-Z]", s): print "Match!" # char class
... # match either at-sign or capital letter
...
>>> if re.search("/d", s): print "Match!" # digits class
...

可以将字符类看作是规则表达式的“原子”,通常会将那些原子组合成“分子”。可以结合使用 分组循环来完成此操作。由括号表示分组:括号中包含的任何子表达式都被看作是用于以后分组或循环的原子。循环则由以下几个运算符中的某一个来表示:"*" 表示“零或多”;"+" 表示“一或多”;"?" 表示“零或一”。例如,请看以下示例:

样本规则表达式

ABC([d-w]*/d/d?)+XYZ

对于要匹配这个表达式的字符串,它必须以 "ABC" 开头、以 "XYZ" 结尾 -- 但它的中间必须要有什么呢?中间子表达式是 ([d-w]*/d/d?),而且后面跟了“一或多”运算符。所以,字符串的中间必须包括一个(或者两个,或者一千个)与括号中的子表达式匹配的字符或字符串。字符串 "ABCXYZ" 不匹配,因为它的中间没有必要的字符。

不过这个内部子表达式是什么呢?它以 d-w 范围内的零或多个字母开头。一定要注意:零字母是有效匹配,虽然使用英语单词 "some"(一些)来描述它,可能会感到很别扭。接着,字符串必须恰好有一个数字;然后有 零或一个附加数字。(第一个数字字符类没有循环运算符,所以它只出现一次。第二个数字字符类有 "?" 运算符。)总而言之,这将翻译成“一个或两个数字”。以下是一些与规则表达式匹配的字符串:

匹配样本表达式的字符串

ABC1234567890XYZ
ABCd12e1f37g3XYZ
ABC1XYZ

还有一些表达式与规则表达式匹配(想一想,它们为什么不匹配):

不匹配样本表达式的字符串

ABC123456789dXYZ
ABCdefghijklmnopqrstuvwXYZ
ABcd12e1f37g3XYZ
ABC12345%67890XYZ
ABCD12E1F37G3XYZ

需要一些练习才能习惯创建和理解规则表达式。但是,一旦掌握了规则表达式,您就具有了强大的表达能力。也就是说,转而使用规则表达式解决问题通常会很容易,而这类问题实际上可以使用更简单(而且更快速)的工具,如 string,来解决。

参考资料

没有更多推荐了,返回首页