如何查找子字符串的索引?

时间:2016-02-22 10:20:48

标签: elixir

寻找相当于Ruby的Elixir:

"john.snow@domain.com".index("@")         # => 9
"john.snow@domain.com".index("domain")    # => 10

5 个答案:

答案 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