mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-05 04:27:44 +00:00
add strbasics.strip (#16280)
This commit is contained in:
@@ -171,6 +171,8 @@ provided by the operating system.
|
||||
dumping (on select signals) and notifying the parent process about the cause
|
||||
of termination.
|
||||
|
||||
- Added `strip` and `setSlice` to `std/strbasics`.
|
||||
|
||||
|
||||
## Language changes
|
||||
|
||||
|
||||
@@ -2753,6 +2753,7 @@ func strip*(s: string, leading = true, trailing = true,
|
||||
## If both are false, the string is returned unchanged.
|
||||
##
|
||||
## See also:
|
||||
## * `strip proc<strbasics.html#strip,string,set[char]>`_ Inplace version.
|
||||
## * `stripLineEnd func<#stripLineEnd,string>`_
|
||||
runnableExamples:
|
||||
let a = " vhellov "
|
||||
|
||||
97
lib/std/strbasics.nim
Normal file
97
lib/std/strbasics.nim
Normal file
@@ -0,0 +1,97 @@
|
||||
#
|
||||
#
|
||||
# The Nim Compiler
|
||||
# (c) Copyright 2021 Nim Contributors
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
## This module provides some high performance string operations.
|
||||
|
||||
const whitespaces = {' ', '\t', '\v', '\r', '\l', '\f'}
|
||||
|
||||
func stripSlice(s: openArray[char], leading = true, trailing = true, chars: set[char] = whitespaces): Slice[int] =
|
||||
## Returns the slice range of `s` which is stripped `chars`.
|
||||
runnableExamples:
|
||||
assert stripSlice(" abc ") == 1 .. 3
|
||||
var
|
||||
first = 0
|
||||
last = high(s)
|
||||
if leading:
|
||||
while first <= last and s[first] in chars: inc(first)
|
||||
if trailing:
|
||||
while last >= first and s[last] in chars: dec(last)
|
||||
result = first .. last
|
||||
|
||||
func setSlice*(s: var string, slice: Slice[int]) =
|
||||
## Inplace version of `substr`.
|
||||
runnableExamples:
|
||||
import std/sugar
|
||||
|
||||
var a = "Hello, Nim!"
|
||||
doassert a.dup(setSlice(7 .. 9)) == "Nim"
|
||||
doAssert a.dup(setSlice(0 .. 0)) == "H"
|
||||
doAssert a.dup(setSlice(0 .. 1)) == "He"
|
||||
doAssert a.dup(setSlice(0 .. 10)) == a
|
||||
doAssert a.dup(setSlice(1 .. 0)).len == 0
|
||||
doAssert a.dup(setSlice(20 .. -1)).len == 0
|
||||
|
||||
|
||||
doAssertRaises(AssertionDefect):
|
||||
discard a.dup(setSlice(-1 .. 1))
|
||||
|
||||
doAssertRaises(AssertionDefect):
|
||||
discard a.dup(setSlice(1 .. 11))
|
||||
|
||||
|
||||
let first = slice.a
|
||||
let last = slice.b
|
||||
|
||||
assert first >= 0
|
||||
assert last <= s.high
|
||||
|
||||
if first > last:
|
||||
s.setLen(0)
|
||||
return
|
||||
template impl =
|
||||
for index in first .. last:
|
||||
s[index - first] = s[index]
|
||||
if first > 0:
|
||||
when nimvm: impl()
|
||||
else:
|
||||
# not JS and not Nimscript
|
||||
when not declared(moveMem):
|
||||
impl()
|
||||
else:
|
||||
moveMem(addr s[0], addr s[first], last - first + 1)
|
||||
s.setLen(last - first + 1)
|
||||
|
||||
func strip*(a: var string, leading = true, trailing = true, chars: set[char] = whitespaces) {.inline.} =
|
||||
## Inplace version of `strip`. Strips leading or
|
||||
## trailing `chars` (default: whitespace characters).
|
||||
##
|
||||
## If `leading` is true (default), leading `chars` are stripped.
|
||||
## If `trailing` is true (default), trailing `chars` are stripped.
|
||||
## If both are false, the string is unchanged.
|
||||
runnableExamples:
|
||||
var a = " vhellov "
|
||||
strip(a)
|
||||
assert a == "vhellov"
|
||||
|
||||
a = " vhellov "
|
||||
a.strip(leading = false)
|
||||
assert a == " vhellov"
|
||||
|
||||
a = " vhellov "
|
||||
a.strip(trailing = false)
|
||||
assert a == "vhellov "
|
||||
|
||||
var c = "blaXbla"
|
||||
c.strip(chars = {'b', 'a'})
|
||||
assert c == "laXbl"
|
||||
c = "blaXbla"
|
||||
c.strip(chars = {'b', 'a', 'l'})
|
||||
assert c == "X"
|
||||
|
||||
setSlice(a, stripSlice(a, leading, trailing, chars))
|
||||
126
tests/stdlib/tstrbasics.nim
Normal file
126
tests/stdlib/tstrbasics.nim
Normal file
@@ -0,0 +1,126 @@
|
||||
discard """
|
||||
targets: "c cpp js"
|
||||
"""
|
||||
|
||||
import std/[strbasics, sugar]
|
||||
|
||||
|
||||
proc teststrip() =
|
||||
var a = " vhellov "
|
||||
strip(a)
|
||||
doAssert a == "vhellov"
|
||||
|
||||
a = " vhellov "
|
||||
a.strip(leading = false)
|
||||
doAssert a == " vhellov"
|
||||
|
||||
a = " vhellov "
|
||||
a.strip(trailing = false)
|
||||
doAssert a == "vhellov "
|
||||
|
||||
a.strip()
|
||||
a.strip(chars = {'v'})
|
||||
doAssert a == "hello"
|
||||
|
||||
a = " vhellov "
|
||||
a.strip()
|
||||
a.strip(leading = false, chars = {'v'})
|
||||
doAssert a == "vhello"
|
||||
|
||||
var c = "blaXbla"
|
||||
c.strip(chars = {'b', 'a'})
|
||||
doAssert c == "laXbl"
|
||||
c = "blaXbla"
|
||||
c.strip(chars = {'b', 'a', 'l'})
|
||||
doAssert c == "X"
|
||||
|
||||
block:
|
||||
var a = "xxxxxx"
|
||||
a.strip(chars={'x'})
|
||||
doAssert a.len == 0
|
||||
|
||||
block:
|
||||
var a = "x"
|
||||
a.strip(chars={'x'})
|
||||
doAssert a.len == 0
|
||||
|
||||
block:
|
||||
var a = "x"
|
||||
a.strip(chars={'1'})
|
||||
doAssert a.len == 1
|
||||
|
||||
block:
|
||||
var a = ""
|
||||
a.strip(chars={'x'})
|
||||
doAssert a.len == 0
|
||||
|
||||
block:
|
||||
var a = "xxx xxx"
|
||||
a.strip(chars={'x'})
|
||||
doAssert a == " "
|
||||
|
||||
block:
|
||||
var a = "xxx wind"
|
||||
a.strip(chars={'x'})
|
||||
doAssert a == " wind"
|
||||
|
||||
block:
|
||||
var a = "xxx iii"
|
||||
a.strip(chars={'i'})
|
||||
doAssert a == "xxx "
|
||||
|
||||
block:
|
||||
var a = "xxx iii"
|
||||
doAssert a.dup(strip(chars = {'i'})) == "xxx "
|
||||
doAssert a.dup(strip(chars = {' '})) == "xxx iii"
|
||||
doAssert a.dup(strip(chars = {'x'})) == " iii"
|
||||
doAssert a.dup(strip(chars = {'x', ' '})) == "iii"
|
||||
doAssert a.dup(strip(chars = {'x', 'i'})) == " "
|
||||
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0
|
||||
|
||||
block:
|
||||
var a = "x i"
|
||||
doAssert a.dup(strip(chars = {'i'})) == "x "
|
||||
doAssert a.dup(strip(chars = {' '})) == "x i"
|
||||
doAssert a.dup(strip(chars = {'x'})) == " i"
|
||||
doAssert a.dup(strip(chars = {'x', ' '})) == "i"
|
||||
doAssert a.dup(strip(chars = {'x', 'i'})) == " "
|
||||
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0
|
||||
|
||||
block:
|
||||
var a = ""
|
||||
doAssert a.dup(strip(chars = {'i'})).len == 0
|
||||
doAssert a.dup(strip(chars = {' '})).len == 0
|
||||
doAssert a.dup(strip(chars = {'x'})).len == 0
|
||||
doAssert a.dup(strip(chars = {'x', ' '})).len == 0
|
||||
doAssert a.dup(strip(chars = {'x', 'i'})).len == 0
|
||||
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0
|
||||
|
||||
block:
|
||||
var a = " "
|
||||
doAssert a.dup(strip(chars = {'i'})) == " "
|
||||
doAssert a.dup(strip(chars = {' '})).len == 0
|
||||
doAssert a.dup(strip(chars = {'x'})) == " "
|
||||
doAssert a.dup(strip(chars = {'x', ' '})).len == 0
|
||||
doAssert a.dup(strip(chars = {'x', 'i'})) == " "
|
||||
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0
|
||||
|
||||
|
||||
block:
|
||||
var a = "Hello, Nim!"
|
||||
doassert a.dup(setSlice(7 .. 9)) == "Nim"
|
||||
doAssert a.dup(setSlice(0 .. 0)) == "H"
|
||||
doAssert a.dup(setSlice(0 .. 1)) == "He"
|
||||
doAssert a.dup(setSlice(0 .. 10)) == a
|
||||
doAssert a.dup(setSlice(1 .. 0)).len == 0
|
||||
doAssert a.dup(setSlice(20 .. -1)).len == 0
|
||||
|
||||
|
||||
doAssertRaises(AssertionDefect):
|
||||
discard a.dup(setSlice(-1 .. 1))
|
||||
|
||||
doAssertRaises(AssertionDefect):
|
||||
discard a.dup(setSlice(1 .. 11))
|
||||
|
||||
static: teststrip()
|
||||
teststrip()
|
||||
Reference in New Issue
Block a user