使用搜索运算符仅在存在匹配项时查找
Using Search operator to find out only if there is a match
在 Dyalog APL 中使用运算符 ⎕S 时,我只对是否匹配感兴趣,因此表达式
('foo' ⎕S F) 'foo' 'bar' 'foofoo'
应该评估为
.→----.
|1 0 1|
'~----'
什么函数(或字符串)F 会实现这个?
编辑:这个例子只是为了说明这一点。在实践中,正则表达式可能要复杂得多。
免责声明
⎕S
是一个具有许多功能的强大野兽 - 但我不确定它是否适合执行检查是否存在匹配这样简单的工作。但也许您试图简化一个复杂的问题 - 或者也许我对 ⎕S
的理解不够透彻。
所以我想展示我将如何解决给定的问题,然后看看潜在的 ⎕S
-approaches.
查找⍷
Find returns 一个布尔向量,在搜索字符串的起始位置。
所以我会在每个向量中找到一个,然后是 ∨/
(or-reduce) 以确定是否存在匹配项:
∨/¨'foo'∘⍷¨'foo' 'bar' 'foofoo'
1 0 1
⎕S
使用 ⎕S,您甚至可以在嵌套参数上使用正则表达式进行搜索。所以我们需要使用每个运算符 ¨
对 3 个向量中的每一个应用 ⎕S f
。
{('foo'⎕S f)⍵}¨'foo' 'bar' 'foofoo'
那么它可以做很多事情return:
- 任何匹配的长度:使用
f
=转换代码1
,它将return匹配字符串的长度.由于我们有一个固定的模式,它可以是任意数量的 3(零到 n)。在你的例子中:
{('foo'⎕S 1 )⍵}¨'foo' 'bar' 'foofoo'
┌─┬┬───┐
│3││3 3│
└─┴┴───┘
最后,检查我们是否有任何 3s,我们得到了想要的结果:
3∊¨{('foo'⎕S 1 )⍵}¨'foo' 'bar' 'foofoo'
1 0 1
- 匹配字符串本身。使用转换模式
&
,它将 return 匹配的字符串:
{('foo'⎕S '&' )⍵}¨'foo' 'bar' 'foofoo'
┌─────┬┬─────────┐
│┌───┐││┌───┬───┐│
││foo││││foo│foo││
│└───┘││└───┴───┘│
└─────┴┴─────────┘
检查是否有匹配,我们就完成了:
0<≢¨{('foo'⎕S '&' )⍵}¨'foo' 'bar' 'foofoo'
1 0 1
- 最后,也用 转换函数 覆盖那个。为找到的每个匹配项调用 TF 并传递一个名称空间,其中包含描述匹配项的各种字段。 (help 记录了各种可能性,我将使用
.Lengths
,它在前面的示例中给出了相同的转换代码 1
)
{('foo'⎕S {⍵.Lengths} )⍵}¨'foo' 'bar' 'foofoo'
┌───┬┬─────┐
│┌─┐││┌─┬─┐│
││3││││3│3││
│└─┘││└─┴─┘│
└───┴┴─────┘
0<≢¨{('foo'⎕S {⍵.Lengths} )⍵}¨'foo' 'bar' 'foofoo'
1 0 1
实际上,我们根本不需要 Lengths
- 我们可以检查它是否收到任何呼叫:
∨/¨{('foo'⎕S {0<≢⍵} )⍵}¨'foo' 'bar' 'foofoo'
1 0 1
结束
我希望这能给你一些想法:)
(≢'foo'⎕S 3⍠'ML'1)¨'foo' 'bar' 'foofoo'
1 0 1
这里发生了什么?
⎕S 3
returns 从 0 开始匹配的模式(所以如果你只有一个模式,它总是 0)
⍠'ML'1
将匹配限制设置为 1,因此 ⎕S
不会在找到第一个匹配项后继续搜索元素。这确保了每个结果最多有一个元素,并且还通过在我们已经足够了解时不进一步搜索来提高性能——是一个匹配项。
(
…)¨
是必要的,因为我们必须分别搜索每个字符向量。如果我们只是想知道该模式是否出现在文档中的任何地方,我们不需要这个。
≢
计算每个结果中模式索引的数量。由于我们设置了匹配限制,每个结果将是 1 元素向量(如果找到)或 0 元素向量(如果未找到),因此我们的总体结果将是我们想要的布尔向量。
值得注意的是⎕S
会分析你的搜索模式,如果搜索不需要正则表达式,它会使用更快的搜索算法,所以你可以依靠⎕S
而不担心需要使用 ⍷
来获得简单模式的最佳性能。
在 Dyalog APL 中使用运算符 ⎕S 时,我只对是否匹配感兴趣,因此表达式
('foo' ⎕S F) 'foo' 'bar' 'foofoo'
应该评估为
.→----.
|1 0 1|
'~----'
什么函数(或字符串)F 会实现这个?
编辑:这个例子只是为了说明这一点。在实践中,正则表达式可能要复杂得多。
免责声明
⎕S
是一个具有许多功能的强大野兽 - 但我不确定它是否适合执行检查是否存在匹配这样简单的工作。但也许您试图简化一个复杂的问题 - 或者也许我对 ⎕S
的理解不够透彻。
所以我想展示我将如何解决给定的问题,然后看看潜在的 ⎕S
-approaches.
查找⍷
Find returns 一个布尔向量,在搜索字符串的起始位置。
所以我会在每个向量中找到一个,然后是 ∨/
(or-reduce) 以确定是否存在匹配项:
∨/¨'foo'∘⍷¨'foo' 'bar' 'foofoo'
1 0 1
⎕S
使用 ⎕S,您甚至可以在嵌套参数上使用正则表达式进行搜索。所以我们需要使用每个运算符 ¨
对 3 个向量中的每一个应用 ⎕S f
。
{('foo'⎕S f)⍵}¨'foo' 'bar' 'foofoo'
那么它可以做很多事情return:
- 任何匹配的长度:使用
f
=转换代码1
,它将return匹配字符串的长度.由于我们有一个固定的模式,它可以是任意数量的 3(零到 n)。在你的例子中:
{('foo'⎕S 1 )⍵}¨'foo' 'bar' 'foofoo'
┌─┬┬───┐
│3││3 3│
└─┴┴───┘
最后,检查我们是否有任何 3s,我们得到了想要的结果:
3∊¨{('foo'⎕S 1 )⍵}¨'foo' 'bar' 'foofoo'
1 0 1
- 匹配字符串本身。使用转换模式
&
,它将 return 匹配的字符串:
{('foo'⎕S '&' )⍵}¨'foo' 'bar' 'foofoo'
┌─────┬┬─────────┐
│┌───┐││┌───┬───┐│
││foo││││foo│foo││
│└───┘││└───┴───┘│
└─────┴┴─────────┘
检查是否有匹配,我们就完成了:
0<≢¨{('foo'⎕S '&' )⍵}¨'foo' 'bar' 'foofoo'
1 0 1
- 最后,也用 转换函数 覆盖那个。为找到的每个匹配项调用 TF 并传递一个名称空间,其中包含描述匹配项的各种字段。 (help 记录了各种可能性,我将使用
.Lengths
,它在前面的示例中给出了相同的转换代码1
)
{('foo'⎕S {⍵.Lengths} )⍵}¨'foo' 'bar' 'foofoo'
┌───┬┬─────┐
│┌─┐││┌─┬─┐│
││3││││3│3││
│└─┘││└─┴─┘│
└───┴┴─────┘
0<≢¨{('foo'⎕S {⍵.Lengths} )⍵}¨'foo' 'bar' 'foofoo'
1 0 1
实际上,我们根本不需要 Lengths
- 我们可以检查它是否收到任何呼叫:
∨/¨{('foo'⎕S {0<≢⍵} )⍵}¨'foo' 'bar' 'foofoo'
1 0 1
结束
我希望这能给你一些想法:)
(≢'foo'⎕S 3⍠'ML'1)¨'foo' 'bar' 'foofoo'
1 0 1
这里发生了什么?
⎕S 3
returns 从 0 开始匹配的模式(所以如果你只有一个模式,它总是 0)
⍠'ML'1
将匹配限制设置为 1,因此 ⎕S
不会在找到第一个匹配项后继续搜索元素。这确保了每个结果最多有一个元素,并且还通过在我们已经足够了解时不进一步搜索来提高性能——是一个匹配项。
(
…)¨
是必要的,因为我们必须分别搜索每个字符向量。如果我们只是想知道该模式是否出现在文档中的任何地方,我们不需要这个。
≢
计算每个结果中模式索引的数量。由于我们设置了匹配限制,每个结果将是 1 元素向量(如果找到)或 0 元素向量(如果未找到),因此我们的总体结果将是我们想要的布尔向量。
值得注意的是⎕S
会分析你的搜索模式,如果搜索不需要正则表达式,它会使用更快的搜索算法,所以你可以依靠⎕S
而不担心需要使用 ⍷
来获得简单模式的最佳性能。