2017-09-15 20 views
1

给定一个输入字符串,我想只使用正则表达式来查找字符串中以特定顺序存在的特定字符的次数。我一直使用正则表达式来匹配表达式,但从不计数字符。不太确定如何去做。所以我只使用模式匹配寻找解决这个问题的方法。如何统计字符串中某些特定的前导字符的数量,仅使用Regex?

例如说我的例子字符串S =“0004fhjs0sjk0” ,我需要计算的领先数“0”字符串s,这是3在这种情况下。如何定义它返回计数(3这里)

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

我已经实现了使用递归解决方案的功能,但我想用正则表达式来做到这一点。

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) 
+0

'字符'只有一个码点或者它可以是一个长字符串?另外,你是否尝试自己实现这一点? (如果是的话,你应该添加非工作代码)。 – Dogbert

+0

对不起,我更新了这个问题。我使用递归解决了它,但想知道Elixir中是否有其他更好的方法来实现它,主要是通过使用模式匹配而不是检查单个字符。 – Shubh77

回答

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有价值的评论,但是这是一个习惯问题。

+2

我会用'“0”<> rest'而不是'<<“0”,rest :: binary >>'。 – Dogbert

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将不再有意义。

相关问题