I want to convert a string to snake-case
My code to split string:
from re import re, split
echo "createdAt".split(re"\B(?=[A-Z])")
Expected result: @["created", "At"]
But I got: @["createdA", "t"]
This result look like are counter-intuitive.
How can I use re module to get the expected result?
Use something like this:
import strutils
proc toSnakeCase(s: string): string =
result = newStringOfCap(s.len + 3)
for i in 0..<s.len:
if s[i] in {'A'..'Z'}:
if i > 0 and s[i-1] in {'a'..'z'}:
result.add '_'
result.add toLowerAscii(s[i])
else:
result.add s[i]
echo toSnakeCase("fooBarBaz Yes")
Regexes are often a poor tool.
Thank you, Araq
Your code help me a lot.
and if you like to use regex, a probably clumsy solution is
import re
proc mySplit(s:string,rx:Regex) : seq[string] =
var
start= -1
let sl = len(s)
while true :
let pos= s.find(rx,start+1)
if pos >= 0 :
if start >= 0 :
result.add(s[start..pos-1])
else :
result.add(s[start+1..pos-1])
start = pos
else :
if start >= 0 :
result.add(s[start..^1])
else :
result.add(s)
break
let
myStr= "createdAt"
sepRex = re"\B(?=[A-Z])"
echo mySplit("createdAt",re"\B(?=[A-Z])")
echo mySplit("createdAtEnd",re"\B(?=[A-Z])")
Thank you, @HJarausch
And I found there are another regex engine in stdlib: nre
split function from nre module can work as expected
from nre import split, re
echo "fooBarTest".split(re"\B(?=[A-Z])")