nim文字列操作

# 概要
nimの文字列操作関連処理をコツコツと書いていく予定
## 以下メモ
### 文字種チェック
```nim
import strutils,pegs,unicode
block:
  echo "アルファベットか？ " & $"abc".isAlpha
  echo "数値・アルファベットか？ " & $"123".isAlphaNumeric
  echo "空白か？ " & $"\t".isSpace
  echo "空白か？ " & $" ".isSpace
  echo "空白か？ " & $"\n".isSpace
  echo "小文字か？ " & $"abc".isLower
  echo "大文字か？ " & $"ABC".isUpper
```
```
(stdout)
アルファベットか？ true
数値・アルファベットか？ true
空白か？ true
空白か？ true
空白か？ true
小文字か？ true
大文字か？ true
```
### 大文字・小文字変換
```nim
import strutils,pegs,unicode
block:
  echo "abc".toUpper
  echo "ABC".toLower
```
```
(stdout)
ABC
abc
```
### キャピタライズ・ノーマライズ
```nim
import strutils,pegs,unicode
block:
  # 先頭１文字だけ大文字
  echo "abc_def".capitalize
  # アンスコを除去
  echo "Abc_Def".normalize
```
```
(stdout)
Abc_def
abcdef
```
### 文字列比較
```nim
import strutils,pegs,unicode
block:
  # 大文字・小文字関係なく検索
  echo "abc".cmpIgnoreCase("ABC")
  # 大文字・小文字・スタイルに関係なく検索
  echo "abcdef".cmpIgnoreStyle("ABC_DEF")
```
```
(stdout)
0
0
```
### トリム
```nim
import strutils,pegs,unicode
block:
  echo "[" & "   strip   ".strip & "]"
```
```
(stdout)
[strip]
```
### 改行付き文字列
```nim
import strutils,pegs,unicode
block:
  # 改行で分解
  let lines = "a\nb\nc\n"
  for line in lines.splitLines :
    echo line
  # 行数をカウント
  echo lines.countLines
```
```
(stdout)
a
b
c

3
```
### 分割(split)
```nim
import strutils,pegs,unicode
block:
  for x in "A,B,C".split(',') :
    echo x
  for x in "D,E,F".split(",") :
    echo x
  for x in "G , H, I".split({',',' '}) :
    echo x
```
```
(stdout)
A
B
C
D
E
F
G
H
I
```
### 文字列・数値変換
```nim
import strutils,pegs,unicode
block:
  echo 123.intToStr & " is 123"
  echo "123".parseInt + 123
  echo "123456789".parseBiggestInt
  echo "3.141592653589793".parseFloat
  echo "0xFF".parseHexInt
  echo "020".parseOctInt
  echo 1000.toOct(5)
  echo 255.toBin(8)
```
```
(stdout)
123 is 123
246
123456789
3.141592653589793
255
16
01750
11111111
```
### Boolean
```nim
import strutils,pegs,unicode
block:
  echo "1".parseBool , "," , "0".parseBool
  echo "y".parseBool , "," , "n".parseBool
  echo "yes".parseBool , "," , "no".parseBool
  echo "on".parseBool , "," , "off".parseBool
  echo "true".parseBool , "," , "false".parseBool
```
```
(stdout)
true,false
true,false
true,false
true,false
true,false
```
### 文字列 → enum 変換
```nim
import strutils,pegs,unicode
block:
  type
    Direction = enum
      north, east, south, west
  echo ord(north) , "," , north
  echo parseEnum[Direction]("north")
```
```
(stdout)
0,north
north
```
### 繰り返し
```nim
import strutils,pegs,unicode
block:
  echo 'A'.repeat(4)
  echo "ABC".repeat(4)
```
```
(stdout)
AAAA
ABCABCABCABC
```
### 左寄せ
```nim
import strutils,pegs,unicode
block:
  echo align("abc", 4) == " abc"
  echo align("a", 0) == "a"
  echo align("1232", 6) == "  1232"
  echo align("1232", 6, '0') == "001232"
```
```
(stdout)
true
true
true
true
```
### ワードラップ
```nim
import strutils,pegs,unicode
block:
  # １０文字で折り返し
  echo wordWrap("ABCDEFGHIJKLMNOPQRSTUVWXYA",10)
  # インデント
  echo indent(wordWrap("ABCDEFGHIJKLMNOPQRSTUVWXYA",10), 4)
  # アンインデント
  echo unindent(indent(wordWrap("ABCDEFGHIJKLMNOPQRSTUVWXYZ",10), 4))
```
```
(stdout)
ABCDEFGHIJ
LMNOPQRSTU
VWXYA
    ABCDEFGHIJ
    LMNOPQRSTU
    VWXYA
ABCDEFGHIJ
LMNOPQRSTU
VWXYZ
```
### 部分一致
```nim
import strutils,pegs,unicode
block:
  # 先頭一致
  echo "abcdef".startsWith("abc")
  # 末尾一致
  echo "abcdef".endsWith("def")
  # 途中の文字位置から特定の文字列になっているか
  echo "abc_def_ghi".continuesWith("def",4)
  echo "abc_def_ghi".continuesWith("def",1)
```
```
(stdout)
true
true
true
false
```
### セパレータを追加
```nim
import strutils,pegs,unicode
block:
  var arr = "["
  for x in items([2, 3, 5, 7, 11]):
    addSep(arr, startLen=len("["))
    add(arr, $x)
    echo arr
  add(arr, "]")
  echo arr
```
```
(stdout)
[2
[2, 3
[2, 3, 5
[2, 3, 5, 7
[2, 3, 5, 7, 11
[2, 3, 5, 7, 11]
```
### 結合(join)
```nim
import strutils,pegs,unicode
block:
  let lines = ["ABC","DEF","GHI"]
  echo lines.join("_")
```
```
(stdout)
ABC_DEF_GHI
```
### 文字列検索
```nim
import strutils,pegs,unicode
block:
  # 先頭から検索
  echo "abc_abc".find("a")
  echo "abc_abc".find({'b','c'})
  # 末尾から検索
  echo "abc_abc".rfind("a")
```
```
(stdout)
0
1
4
```
### 任意の文字をカウント
```nim
import strutils,pegs,unicode
block:
  echo "abc_abc".count("a")
  echo "abc_abc".count({'a','b'})
```
```
(stdout)
2
4
```
### 文字列から文字列を検索
```nim
import strutils,pegs,unicode
block:
  echo "abc_def_ghi".contains("_")
```
```
(stdout)
true
```
### 文字列置換
```nim
import strutils,pegs,unicode
block:
  # 単純な置換
  echo "abc_def_ghi".replace("_","-")
  echo "abc_def_ghi".replace("_","_-")
  # 単語単位の置換
  echo "(ng)I hava a pen and pencil".replace("pen","notebook")
  echo "(ok)I hava a pen and pencil".replaceWord("pen","notebook")
```
```
(stdout)
abc-def-ghi
abc_-def_-ghi
(ng)I hava a notebook and notebookcil
(ok)I hava a notebook and pencil
```
### 削除
```nim
import strutils,pegs,unicode
block:
  var s = "ABCDEF"
  delete(s,0,2)
  echo s
```
```
(stdout)
DEF
```
### 文字列に差し込む
```nim
import strutils,pegs,unicode
block:
  echo "1234567".insertSep(sep=',',3)
```
```
(stdout)
1,234,567
```
### エスケープ・アンエスケープ
```nim
import strutils,pegs,unicode
block:
  echo """abc"def\n""".escape
  echo """abc"def\n""".escape.unescape
```
```
(stdout)
"abc\"def\\n"
abc"def\n
```
### 変数名チェック( [A-Z]\w* )
```nim
import strutils,pegs,unicode
block:
  echo "abc".validIdentifier
  echo "Abc".validIdentifier
  echo "_abc".validIdentifier
  echo "$abc".validIdentifier
```
```
(stdout)
true
true
true
false
```
### リーベンシュタイン距離
```nim
import strutils,pegs,unicode
block:
  echo "ABC".editDistance("ABC")
  echo "ABC".editDistance("AbC")
```
```
(stdout)
0
1
```
### フォーマット
```nim
import strutils,pegs,unicode
block:
  echo "$1 eats $2." % ["The cat", "fish"]
  echo "$# eats $#." % ["The cat", "fish"]
  echo "$animal eats $food." % ["animal", "The cat", "food", "fish"]
```
```
(stdout)
The cat eats fish.
The cat eats fish.
The cat eats fish.
```
### トークナイザ
```nim
import strutils,pegs,unicode
block:
  for word in tokenize("  this is an  example  "):
    if word.isSep :
      writeLine(stdout, word)
```
```
(stdout)
(token:   , isSep: true)
(token:  , isSep: true)
(token:  , isSep: true)
(token:   , isSep: true)
(token:   , isSep: true)
```