寻找相当于Ruby的Elixir:
"john.snow@domain.com".index("@") # => 9
"john.snow@domain.com".index("domain") # => 10
答案 0 :(得分:13)
我认为没有任何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
。
答案 1 :(得分:11)
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
答案 2 :(得分:6)
您可以使用Regex.run/3
并将其return: :index
作为选项传递:
iex(5)> [{start, len}] = Regex.run(~r/abc/, " abc ", return: :index)
[{1, 3}]
答案 3 :(得分:4)
您可以使用:binary.match/3
获取字节索引{index, length} = :binary.match("aéiou", "o")
{4, 1}
如果您想要字符串中的位置,请使用:
"aéiou" |> to_char_list() |> Enum.find_index(&(&1 == ?o))
3
String模块文档解释了字节长度和字符串长度之间的差异。
答案 4 :(得分:0)
# 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