罗兰在MATLAB的艺术

把想法变成MATLAB

请注意

罗兰在MATLAB的艺术已经退休,不会被更新。

学习去爱正则表达式

今天我想介绍一下客人的博客莎拉等Zaranek工作的MATLAB在MathWorks营销团队。莎拉此前曾使用MATLAB的gpu。莎拉将讨论她是怎么开始使用正则表达式。

内容

概述

在过去的几年中,我有幸做了几个客人罗兰的博客文章。通常,我对我的博客知道很好——但这次是不同的。我想写关于正则表达式,谈一下我是如何开始使用它们,并展示一些例子,我创建了。我的背景是在计算地球物理,所以我很熟悉数字,并行计算和一大堆其他MATLAB的东西。但是,我从来没有真正操纵字符串。在我小处理字符串时,我发现功能strfind就足够让我完成的工作。

好吧,然后我发现科迪。如果你还没有开始使用科迪,你可能不理解是多么让人上瘾!所有这些很酷的小编码MATLAB谜题,我只是不能停止。然而,我发现自己非常一致地跳过任何挑战和操纵字符串。我认为这是一个迹象表明我的MATLAB技能,我有一个洞,我需要开始补救它。所以,我开始寻求更多的了解正则表达式。我学得越多,跟他们玩,他们更有多么强大,给我留下了深刻的印象。

如果您是正则表达式,我希望这篇文章能激励你开始拥抱。如果你是一个经验丰富的正则表达式的用户,希望你会喜欢我的一些例子和找到我的新发芽的正则表达式的兴奋有趣。你可能想查看帖子由我们的一个开发人员,杰森·布雷斯劳,讨论之间的差异的Perl和MATLAB实现正则表达式。同时,请在评论中考虑发布你的最喜欢的例子在文章结束。

最基本的

正则表达式是一种描述文本中的一种模式。使用正则表达式,可以匹配或改变部分(子)的一个文本字符串匹配的描述模式。正则表达式是发现在文本编辑器和一系列的语言(包括Perl、Java、Ruby,当然,MATLAB。

在这篇文章中,我将关注功能正则表达式。还有其他几个正则表达式在MATLAB相关函数,所以我鼓励你阅读更多有关他们

在MATLAB中,调用语法正则表达式我们将使用:

[selected_outputs] = regexp(字符串、expr outselect)

字符串是字符串或字符串单元阵列,我想寻找模式。expr是指定的正则表达式模式我想匹配。outselect指定输出我想从函数,包括等选项的位置开始或结束的表达式相匹配的子串,和文本输入字符串的子字符串相匹配的模式。所有可能的输出选项中详细解释文档

足够的背景,让我们看看三个例子的地方我最近一直在使用正则表达式。

例# 1 -把字符串分解为单独的单词

这个例子是所以看似简单,但完全是如此有用,我不得不把它。你曾经想要一个字符串分割成单独的单词吗?这对你是否在一个简单的步骤。

让我们浏览一下基本的语法。首先,我需要定义表达式指定模式我想匹配的字符串。在这种情况下,我想找到空间,所以我选择' \ s '这表示任何空白字符。这是所谓的“字符类型”,和它代表一组特定的字符或某种类型的角色。文档有一个列表可能的字符类型可以使用正则表达式

然后我决定我想要的输出正则表达式。在本例中,我选择分裂,这表明我想把字符串分割成部分由(即匹配的子字符串表达式。,将字符串分解成子字符串基于空间)。

mystring =“我的名字叫莎拉等Zaranek”;mystring splitstring = regexp (,' \ s ',“分裂”);disp (splitstring)
“我”“名称”“是”“莎拉”“等待”“Zaranek”

现在初始字符串分解成单元阵列包含所有单独的单词在句子中的。

我可以做类似的事情如果我想基于句子拆分字符串。在本例中,我想分的空间立即开始!,?。这是稍微复杂一点,我可能想要使用一个看看操作符。

首先,我必须找出如何让正则表达式知道我想匹配从一组可能的字符;为此,我将可能的匹配包含在方括号。(! ?)意味着匹配任何字符的上市。

其次,我表明我想匹配空间之前的字符。所以我用一个看看运营商。看看你周围看看运营商让一个字符串的当前位置。例如,向前看(向右)位置的测试如果找到一个特定的表达式,使用超前算子(? = expr)。在本例中,我使用一个向后插入运算符(? < = expr)我可以看后面的当前位置测试如果找到一个表达式。特别是,我正在寻找匹配,我找到一个空间,当我“向后看”的空间(左边的)我找到!,。和?。我,再一次,可以使用分裂分裂的输出选择匹配的子串。

mystring =“我的名字叫萨拉。我爱MATLAB !你呢?”;mystring splitstring = regexp (,‘(? < = (! ?))\ s ',“分裂”);disp (splitstring)
“我的名字叫萨拉。“我爱MATLAB !“你呢?”

例# 2 -创建短标签的阴谋

在这个例子中,我做了一个问题,涉及数据从多个位置在加州。我想阴谋数据从多个位置在同一情节和标签每一组相应的数据。然而,由于城市名字是长,有很多数据在我的阴谋,我想创建缩写城市名称标签。

我的第一次尝试是做下面列出的命令。首先,我想要找到的位置单元阵列中的大写字母的字符串。要做到这一点,我可以使用的[a -ž]字符范围操作符,允许我指定范围内的任意字符的资本资本Z(即任何大写字母)。默认的输出正则表达式和一个输出变量是给我的位置匹配字符串的开始,我使用。我可以使用这些位置创建缩写的城市名称以大写字母,一个字母向右它来创建我的缩写。

正则表达式返回一个1 x 6单元阵列,每个元素控股大写字母的位置对应的输入字符串。

提取的大写字母和字母旁边,我使用cellfun操作每个元素的输出指数和输入字符串。我使用排序指数为单调递增的顺序进行排序。该方法假设我没有大写字母排成一行。

凯利= {“班尼特谷”,“主教”,“卡米诺”,“Santa Rosa”,加州大学河滨分校的,“温莎”};idx = regexp(凯利,“[a - z]”);shortLabels = cellfun(@(标签,idx)标签(排序([idx idx + 1])),idx凯利,“UniformOutput”、假);disp (shortLabels)
“BeVa”“Bi”“Ca”“萨诺”“加州大学国际扶轮' ' Wi '

我学到了更多关于正则表达式的时候,我发现了一个新的和更清洁的方式来完成相同的任务。我可以扩展模式是任何字符大写字母后跟。一个点()用于表示任何单个字符。

因为这实际上提取子字符串匹配的我感兴趣,我不需要输出指标。相反,我只是表明我希望通过指定匹配的子字符串“匹配”正如我的输出选项。那么,我将从每个城市名称匹配的子字符串为一个城市通过使用缩写cellfun

shortLabels2 = regexp(凯利,“[a - z]。”,“匹配”);shortLabelsFinal = cellfun (@ (x) [x {:}], shortLabels2,“UniformOutput”、假);disp (shortLabelsFinal)
“BeVa”“Bi”“Ca”“萨诺”“加州大学国际扶轮' ' Wi '

例# 3 -发现数据被重复的字母

在本例中,我使用文本字符串,看起来像' CC = 0 / CT = 1 / TT = 5375”。我想提取出遵循重复字母的数字值。这是基因数据,在这个特定的字符串我想提取的人数与CC或TT基因型

有一些方法处理这个问题。因为只有几个字母,可以现在(a、G、C、T),我可以使用|作为替代匹配操作符。与使用[]如上例1,|让我结合多个表达式的匹配可能的替代方法。如果你将这些方括号的替代品,[],它将每个字符包括|的列表可能的字符匹配,所以一定要用括号附上,()

这种差异在fiedl的用于检查电子邮件地址的说明精通正则表达式。注意:他使用字符类参考使用[]。他,“不要混淆交替与字符类…一个字符类可以完全匹配一个字符,这是真的,无论时间长短指定可接受的字符列表。交替,另一方面,可以有任意长度的选择,每个文本与其他无关”。

我第一次创建一个表达式代表可能的双字母后跟一个等号,(CC TT AA | | | GG) =。然后,我这个表达式在向后插入操作员因为我想找到数字立即开始通过这种模式,(? < = (CC TT AA | | | GG) =)

我使用\ d +定义我想匹配。这是由元字符\ d代表数字和吗+这是一个量词。量词用于匹配连续出现的一个模式和一个字符串。在这种情况下,+意味着一次或多次匹配模式。

当这些作品放在一起,他们让一个表达式代表一个数字前面都有一个双CC, TT, AA,或GG和一个等号,(? < = (CC TT AA | | | GG) =) \ d +

geneString =' CC = 0 / CT = 1 / TT = 5375 ';doubleValues1 = regexp (geneString,TT (? < = (CC | | AA | GG) =) \ d + ',“匹配”);disp (doubleValues1)
' 0 ' ' 5375 '

或者,我可以使用令牌找出字母重复。尽管在这种情况下,因为我有一个相对较短的列表可能重复字母,令牌可能有点笨手笨脚的。然而,令牌可以帮助我找到任何重复的信,是有用的,如果我不想写出所有可能的双字母组合。

括号允许你将多个字符与指定表达式匹配发现令牌。令牌让你记住匹配的元素,并允许你匹配字符串的其他部分与这些捕获的元素。使用\ N,我可以参考第n个匹配标记在我的表情。

在这种情况下,我想找字母字符串,看看下一个字母匹配前面的字母。我通过使用\ w找到一封信和分组在括号使它成为一个令牌。然后,我标记的参考\ 1表明我们想要找到实例匹配的信是重复的。我遵循的=和一个\ d +像以前一样。我捕获输出的数值输出标记和说明我想要的\ d +是一个令牌通过将它包含在圆括号中。通过选择令牌作为输出选项,我可以得到匹配的令牌,而不是整个匹配字符串。然后我可以使用cellfun提取第二个令牌(数值)的输出。

doubleValues2 = regexp (geneString,”(\ w) \ 1 = (\ d +) ',“令牌”);celldisp (doubleValues2);
C doubleValues2 doubleValues2 {1} {1} = {1} {2} = 0 doubleValues2 {2} {1} = T doubleValues2 {2} {2} = 5375
doubleValues2 = cellfun (@ x (x) {2}, doubleValues2,“UniformOutput”、假);disp (doubleValues2);
' 0 ' ' 5375 '

结论

我希望你喜欢这篇文章在正则表达式。这仅仅是冰山的一角,正则表达式可以做的还有很多。检查文档更多的例子,玩得开心!

如果你正在使用正则表达式,你有什么建议对于那些新使用正则表达式?如果您是使用正则表达式,你有什么问题开始?让我知道你的评论这篇文章




发表与MATLAB®R2012b

|