罗兰关于MATLAB的艺术

将想法转化为MATLAB

搜索字符串时的压力?

当你要搜索一个字符串模式,而不仅仅是一个特定的字符串时,你的手会不会变得粘乎乎的?是否有挣扎的想法正则表达式让你出汗吗?

好吧,别再担心了!现在,使用新的模式在MATLAB环境下功能。在某些情况下,你甚至可以侥幸逃脱惩罚。

对于今天的帖子,我的合著者是Jason Breslau和Curtis Anderson,因为他们知道更多正则表达式还有更多关于功能的细微差别。我们将通过展示几个示例来实现这一点。您可能还想看看Jiro最近的本周精选

内容

示例0:对于那些喜欢regexp的人

如果你爱,这个例子是给你的正则表达式我不明白你为什么要考虑其他事情。您可以使用regexpPattern将您喜欢的正则表达式转换为模式,以便您可以利用代码特性。比较这两种方法,看看某个字符串是否包含在某些文本中。

包含(str regexpPattern (expr))
~ cellfun (isempty,正则表达式(str, expr))

其中哪一个你可以在每次阅读时不必经过逻辑就能快速理解?

现在更多的是给那些真的想跳过的人正则表达式更多。

示例1:计数注释行

假设我想计算MATLAB文件中作为注释(而不是块注释)的行数。下面是如何使用正则表达式

codeFile = fileread (“num2str.m”);评论= regexp (codeFile,“^ \ s * %”“lineanchors”);元素个数(评论)
ans = 37

这很烦人,因为你必须知道lineanchors,而且正则表达式有点丑。另外,它返回了一个索引数组,我们并不真正关心它。相反,试试这个:

count(codeFile, lineBoundary + whitespacpattern +“%”
ans = 37

我们仍然需要读取文件,并查找以%开头的行(忽略前导空格)。

示例2:如何在以元音开头的文件中查找单词

假设我们想要得到一些关于以元音开头的单词的统计数据。

vowelWords = regexpi (codeFile,\ <[五个母音字母][a - z] *’“匹配”);howManyWords =长度(vowelWords)
howManyWords = 176

使用模式,我们首先搜索字母字符,然后只查找以元音开头的单词。

单词= extract(codeFile, letterpattern);vorwelwords1 = words(startwith (words, characterListPattern(“五个母音字母),“IgnoreCase”,真的));howManyWords =长度(vowelWords1)
howManyWords = 176

这里可能有一个更好的方法!根据元音的列表建立一个模式。然后寻找在字母前有边界的东西——一些空格,后面跟着一个元音,然后是单词可能的其余部分。

元音= caseInsensitivePattern (characterListPattern (“aeiou”));vowelWords2Pat = letterBoundary +元音+字母pattern (0,inf);vowelWords2 = extract(codeFile, vowelWords2Pat);howManyWords =长度(vowelWords2)
howManyWords = 176

假设我们只有想要这里的计数,我们可以用调用来替换前两行代码更有效地达到我们的目标。构建复杂模式的工作流的伟大之处在于它为您提供了多功能性。

hmw=计数(代码文件、元音或S2PAT、,“IgnoreCase”,对)
高分子量= 176

或者我可以替换正lettersPattern (0)optionalPattern (lettersPattern).能够为函数提供模式开始包含这是最大的胜利。

最佳实践

我们发现最好是通过连接小块来建立一个模式。它使您更容易理解您在做什么,您在哪里或没有应用大小写敏感性等。

例3:逆向-查找以辅音开头的单词

假设我们想要以辅音开头的单词。这是正则表达式道路

consRegexp = regexpi (codeFile,“\<(?![aeiou])[a-z]+”“匹配”);

使用一种模式

consPat=extract(代码文件,...字母数字边界+...~ lookAheadBoundary (caseInsensitivePattern (characterListPattern (“五个母音字母)))...+ lettersPattern);

最后,两者都不用正则表达式也不是辅音模式。相反,用元音单词开头的否定。这也许是最容易理解的。

conwords = words(~startsWith(words, caseinsensitivpattern (characterListPattern()))“五个母音字母))));

精明的读者会发现这里的答案并不一致。有关详细信息以及如何使答案一致,请参阅最后的附录。

示例4:查找具有特定扩展名的文件

在我们的测试系统中,我们审核了在一个阶段中使用的所有正则表达式,发现其中大约50%可以被替换endsWith没有任何模式。以前我们使用正则表达式但这对这项工作来说是一个巨大的打击。我认为查找具有特定文件扩展名的文件可能是一个常见的用例。例如,

正则表达式(文件名,“美元. txt”)

它有两个bug!你需要isempty,“一次”

~isempty(regexp(文件名,.txt$,'once'))

你还需要避开点,这是每个人都忘记做的。

~isempty(regexp(文件名,\.txt$,'once'))

而现在你只是简单地做了

endsWith(文件名“.txt”)

有趣的是,它没有使用任何模式,而是使用了一个函数,endsWith,这可能需要一个模式。

假设您现在想检查两个不同的扩展。很容易做到的。endsWith金宝app支持多个搜索字符串,并将其视为.这比使用合适的模式进行搜索更快,但有一点限制。

endsWith(文件名,[" . txt ", " .somethingElse "])

显式或

endsWith(文件名“.txt”|“.somethingElse”)

没有扩展名的文件呢

如果文件名以txt或根本没有扩展名结尾怎么办?

endsWith(fileName, '.txt') || ~contains(fileName, '.txt')

这是针对单个文件,没有完整的路径名。

你的搜索进展如何?

你是否能够很好地利用MATLAB中的模式,并能够(或不能)消除一些或所有的使用正则表达式.让我们知道在这里

附录

正如承诺的那样,我将在这里描述为什么辅音答案不一致,以及如何使它们相同。

单词Variable有一组连续的字母。我们有一些名字在num2str代码也使用数字,例如,mat2str.这句话可以翻译成两个词,str.我们可以使用

words = extract(codeFile, alphanumericBoundary…+字母模式+字母数字边界);

这意味着正则表达式版本是:

consRegexp = regexpi (codeFile‘\ <(? ![五个母音字母])[a - z] + \ >”,“比赛”);

和对应的模式:

conat = extract(codeFile,…)alphanumericBoundary +……~ lookAheadBoundary (caseInsensitivePattern (characterListPattern(“五个母音字母”)))……+字母模式+字母数字边界);

唷!那是一口!但也很易读。




与MATLAB®R2020b一起发布

|

评论

要留下评论,请点击在这里登录到您的MathWorks帐户或创建一个新帐户。