【发布时间】:2017-05-10 02:37:36
【问题描述】:
寻找相当于 Ruby 的 Elixir:
"john.snow@domain.com".index("@") # => 9
"john.snow@domain.com".index("domain") # => 10
【问题讨论】:
标签: elixir
寻找相当于 Ruby 的 Elixir:
"john.snow@domain.com".index("@") # => 9
"john.snow@domain.com".index("domain") # => 10
【问题讨论】:
标签: elixir
我认为没有任何 Elixir 包装器,请参阅 #1119。
在此之前您可以直接拨打:binary.match:
iex(1)> :binary.match "john.snow@domain.com", "@"
{9, 1}
iex(2)> :binary.match "john.snow@domain.com", "domain"
{10, 6}
返回值是一个包含索引和匹配长度的元组。您可以通过管道将索引提取到|> elem(0) 或使用模式匹配。
请注意,如果在字符串中找不到子字符串,:binary.match 将返回 :nomatch。
【讨论】:
TL;DR:String.index/2 故意丢失,因为存在更智能的替代方案。 String.split/2 通常会解决根本问题 - 并且性能更好。
我假设我们在这里讨论的是 UTF-8 字符串,并期望干净地处理非 ASCII 字符。
Elixir 鼓励快速编写代码。事实证明,我们通常尝试使用 String.index/2 解决的问题可以以更智能的方式解决,在不降低代码可读性的情况下极大地提高性能。
更智能的解决方案是使用 String.split/2 和/或其他类似的 String 模块函数。 String.split/2 在字节级别上工作,同时仍能正确处理字素。它不会出错,因为两个参数都是字符串! String.index/2 必须在字素级别上工作,在整个字符串中缓慢搜索。
因此,String.index/2 不太可能被添加到语言中,除非出现了现有函数无法彻底解决的非常引人注目的用例。
另请参阅有关此问题的 elixir-lang-core 讨论: https://groups.google.com/forum/#!topic/elixir-lang-core/S0yrDxlJCss
另一方面,Elixir 在其成熟的 Unicode 支持方面非常独特。虽然大多数语言都在代码点级别(俗称“字符”)上工作,但 Elixir 使用更高级别的字素概念。字素是用户认为的一个字符(可以说它是对“字符”的更实际的理解)。字形可以包含多个代码点(而代码点又可以包含多个字节)。
最后,如果我们真的需要索引:
case String.split("john.snow@domain.com", "domain", parts: 2) do
[left, _] -> String.length(left)
[_] -> nil
end
【讨论】:
您可以使用Regex.run/3 并将其作为选项传递return: :index:
iex(5)> [{start, len}] = Regex.run(~r/abc/, " abc ", return: :index)
[{1, 3}]
【讨论】:
Regex.scan/3
您可以使用:binary.match/3获取字节索引
{index, length} = :binary.match("aéiou", "o")
{4, 1}
如果您想要字符串中的位置,请使用:
"aéiou" |> to_char_list() |> Enum.find_index(&(&1 == ?o))
3
String 模块文档解释了字节长度和字符串长度之间的区别。
【讨论】:
str.find 和 javascript 的 str.indexOf 相同。其次,应该尽可能避免使用 Enum.find_index ,因为 elixir 有它的递归模式并且以这种方式进行了优化。如果您不想想太多,这是一种快速的方法。
# index (as INSTR from basic...)
...
import IO, except: [inspect: 1]
puts index "algopara ver", "ver"
def index( mainstring, searchstring) do
tuple = (:binary.match mainstring, searchstring)
if tuple === :nomatch do
0
else
elem(tuple,0)
end
end
...
9
【讨论】: