【问题标题】:Convert string argument to regular expression将字符串参数转换为正则表达式
【发布时间】:2015-09-09 03:00:36
【问题描述】:

在学习python之后尝试进入Julia,我在一些看似简单的事情上磕磕绊绊。我想要一个将字符串作为参数的函数,但使用其中一个参数作为正则表达式来搜索某些内容。所以:

function patterncount(string::ASCIIString, kmer::ASCIIString)
    numpatterns = eachmatch(kmer, string, true)
    count(numpatterns)
end

这有几个问题。首先,eachmatch 期望 Regex 对象作为第一个参数,我似乎无法弄清楚如何转换字符串。在 python 中我会做r"{0}".format(kmer) - 有类似的东西吗?

其次,我显然不明白count函数是如何工作的(from the docs):

count(p, itr) → 整数

计算 itr 中谓词 p 返回 true 的元素数。

但我似乎无法弄清楚仅计算迭代器中有多少东西的谓词是什么。我可以制作一个简单的计数器循环,但我认为它必须内置。我只是找不到它(尝试了文档,尝试搜索所以......没有运气)。

编辑:我也试过numpatterns = eachmatch(r"$kmer", string, true) - 不行。

【问题讨论】:

  • 元问题:这应该分成两个单独的问题吗?

标签: julia


【解决方案1】:

要将字符串转换为正则表达式,请在字符串上调用Regex 函数。

通常,要获取迭代器的长度,您可以使用length 函数。但是,在这种情况下,这不会真正起作用。 eachmatch 函数返回一个Base.RegexMatchIterator 类型的对象,它没有length 方法。因此,您可以按照您的想法使用count。第一个参数(谓词)应该是一个返回 truefalse 的单参数函数,具体取决于您是否要计算迭代器中的特定项目。在这种情况下,该函数可以简单地是匿名函数x->true,因为对于RegexMatchIterator 中的所有x,我们都想计算它。

所以,鉴于这些信息,我会这样编写你的函数:

patterncount(s::ASCIIString, kmer::ASCIIString) = 
    count(x->true, eachmatch(Regex(kmer), s, true))

编辑:我还将第一个参数的名称更改为 s 而不是 string,因为 string 是 Julia 函数。如果我们在这个例子中保持参数名称不变,就不会发生什么可怕的事情,但通常最好不要给变量名称与内置函数名称相同。

【讨论】:

  • Derp - length 和python一样,不知道为什么我没有想到。这两种解决方案都很好用。关于我自己的教育的一个问题。如果s 真的很长,那么迭代器和将所有匹配项加载到数组中是否存在性能差异?编辑:你已经回答了我的第二个问题 - 阅读理解失败
  • 如果匹配项很多,应该使用count(x->true, eachmatch(...)) 解决方案(迭代器版本)更节省内存——而不是将所有匹配项加载到数组中(如matchall 函数会)。不过,我可能会做一些基准测试来验证这一点。
猜你喜欢
  • 2020-07-17
  • 1970-01-01
  • 2012-01-28
  • 2022-11-18
  • 2013-06-09
  • 1970-01-01
  • 2016-08-13
  • 2021-09-16
  • 2016-12-03
相关资源
最近更新 更多