Looking at a simple problem - find the indentation of text in a line and see if it's a comment. Nim version:
import nre
import strutils
let commentChars = {'#', ';'}
let nonspace = re"(\S)"
let line = " ; abc "
var m = line.find(nonspace)
if isSome[RegexMatch](m):
let theMatch = get[RegexMatch](m)
let isComment = theMatch.captures[0][0] in commentChars
let pos = theMatch.captureBounds[0].get().a
echo "$# $#" % [$pos, $isComment]
Python version:
import re
comment_chars = {'#', ';'}
nonspace = re.compile(r"(\S)")
line = " ; abc "
m = nonspace.search(line)
if m:
is_comment = m.groups()[0] in comment_chars
pos = m.start(0)
print("%s %s" % (pos, is_comment))
Not hugely different, yet the Nim version just seems harder to grok. Am I using nre suboptimally?
N.B. I know it's easier with re:
import re
import strutils
let commentChars = {'#', ';'}
let nonspace = re"(\S)"
let line = " ; abc "
var matches = newSeq[string](1)
let m = line.find(nonspace, matches)
let is_comment = matches[0][0] in commentChars
echo "$# $#" % [$m, $is_comment]
Somebody needs to document scanp, it's awesome.
import strscans
from strutils import Whitespace
let line = " ; abc "
var idx = 0
var comment = ""
if scanp(line, idx, *`Whitespace`, {'#',';'}):
let start = idx
if scanp(line, idx, +(~{'\C', '\L', '\0'} -> comment.add($_))):
echo "found a comment ##", comment, "## starting at: ", start
With the awk.nim library
import awk, strutils
let commentChars = "[#]|[;]"
let nonspace = "[^ \t\r\n\f]"
let line = " ; abc "
var pos = match(line, nonspace, theMatch) - 1
if pos > -1:
let isComment = theMatch ~ commentChars
echo "$# $#" % [$pos, $isComment]
Or you can use parseutils:
import parseutils
const line = " ; abc "
const commentChars = {'#', ';'}
var res = ""
let pos = skipUntil(line, commentChars)
if pos != line.len:
let start = pos + 1
discard parseUntil(line, res, '\0', start)
echo("found a comment: ", res, " starting at: ", start)
I tried to use scanp before but it offers no convenience, and so you need to use custom logic and has weird syntax.