如何仅使用正则表达式计算字符串中某些特定前导字符的数量?

时间:2017-09-15 18:28:56

标签: elixir elixir-framework

给定一个输入字符串,我想只使用正则表达式查找前导顺序中字符串中特定字符的出现次数。我总是使用正则表达式来匹配表达式,但从不计算其中的字符。不太确定如何做到这一点。所以我只是在寻找使用模式匹配解决这个问题的方法。

比如说我的示例字符串是 S =“0004fhjs0sjk0” 我需要计算字符串S中前导“0”的数量,在这种情况下 3 。如何定义一个返回计数的函数(这里为3)

def get_leading_zeroes(value, character) do
...
end

我已经使用递归实现了一个解决方案,但我想使用Regex来实现。

def get_leading_zeros(value, count) do
[h|t] = value
if h == "0" do
    get_leading_zeros(t, count+1)
else 
    count
end

get_leading_zeros(value |> String.graphemes, 0)

2 个答案:

答案 0 :(得分:1)

使用递归(更好的模式匹配+尾部优化):

defmodule M do
  def get_leading_zeros(input, acc \\ 0) # declaration for default
  def get_leading_zeros(<<"0", rest :: binary>>, acc),
    do: get_leading_zeros(rest, acc + 1) # recursive call when matches
  def get_leading_zeros(_, acc), do: acc # return accumulated
end
M.get_leading_zeros "0004fhjs0sjk0"
#⇒ 3

使用正则表达式:

with [match] <- Regex.run(~r/\A0*/, "0004fhjs0sjk0"),
  do: String.length(match)

没有额外的电话:

with [{pos, _}] <-
     Regex.run(~r/[^0]/, # negative search
               "0004fhjs0sjk0",
               return: :index, capture: :first), # NOTE return: :index
  do: pos

或反之亦然:

with [{0, pos}] <-
     Regex.run(~r/0*/, # positive search
               "0004fhjs0sjk0",
               return: :index, capture: :first),
  do: pos

请在下面查看@Dogbert的有价值评论,但这是习惯问题。

答案 1 :(得分:0)

def get_leading_char_count(str, char) do
  ~r/^#{char}*/
  |> Regex.run(str)
  |> Enum.at(0)
  |> String.length()
end

get_leading_char_count("0004fhjs0sjk0", 0)
# 3

get_leading_char_count("4fhjs0sjk0", 0)
# 0

注意:我在我的示例中重命名了该函数,因为您将零作为自己示例中的第二个参数传递。如果您传递的数字不是零,则函数名get_leading_zeroes将不再有意义。