「文字列」の編集履歴(バックアップ)一覧はこちら
「文字列」(2017/07/23 (日) 00:22:46) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
#contents
#contents
* 文字列
** リファレンス
- [[GNU Emacs Lispリファレンスマニュアル: 文字列と文字>http://www.bookshelf.jp/texi/elisp-manual/21-2-8/jp/elisp_5.html#SEC71]]
- [[Strings and Characters - GNU Emacs Lisp Reference Manual>http://www.gnu.org/software/emacs/manual/html_node/elisp/Strings-and-Characters.html#Strings-and-Characters]]
- [[Formatting Strings - GNU Emacs Lisp Reference Manual>http://www.gnu.org/software/emacs/manual/html_node/elisp/Formatting-Strings.html]]
** その他
- [[Emacs Lisp の文字列操作まとめ>http://emacs.g.hatena.ne.jp/kiwanami/20110809/1312877192]]
- [[s.el (文字列操作用ライブラリ)>https://github.com/magnars/s.el]]
** 文字列を比較する
string-equal,string=関数を使います。
string=はstring-equalの別名として定義されているので、どちらも同じ機能です。
#highlight(lisp) {{
(string= "abc" "abc") ;=> t
(string= "abc" "ABC") ;=> nil
(string= "AB" "ABC") ;=> nil }}
大文字小文字の区別を考慮する場合はcompare-strings関数を使います。
#highlight(lisp) {{
(compare-strings "ABC" nil nil "abc" nil nil t) ;=> t }}
** 文字列の長さを得る
#highlight(lisp) {{
(length "abcdefg") ;=> 7
(length "日本語") ;=> 3 }}
** 文字列を結合する
concat関数を使います。
#highlight(lisp) {{
; 普通に結合
(concat "abc" "-def") ;=> "abc-def"
(concat "私は" "美味しく食べました") ;=> "私は美味しく食べました"
; nilは無視
(concat "abc" nil "-def")
; 引数なしの場合は空文字列を返す
(concat) ;=> "" }}
mapconcat関数を使えば各文字列の間に区切り文字を挿入することが出来ます。
#highlight(lisp) {{
(mapconcat #'identity '("Hello" "Emacs" "Lisp") "-") ;=> "Hello-Emacs-Lisp" }}
** 繰り返し文字列を生成する
一文字だけの繰り返しならばmake-string関数が使えます。
#highlight(lisp) {{
(make-string 10 ?X) ;=> "XXXXXXXXXX" }}
文字列の繰り返しならば、文字列のシーケンスを作ってそれを結合するのが良いでしょう。
#highlight(lisp) {{
(apply #'concat (make-list 5 "Hello")) ;=> "HelloHelloHelloHelloHello"
(mapconcat #'identity (make-vector 5 "Hello") ",") ;=> "Hello,Hello,Hello,Hello,Hello" }}
** 大文字・小文字に揃える
upcase, downcase関数を使います
#highlight(lisp) {{
(upcase "The cat in the hat") ;=> "THE CAT IN THE HAT"
(downcase "THE CAT IN THE HAT") ;=> "the cat in the hat" }}
** 先頭だけを大文字にする(キャピタライズ)
他の言語に余り無くて便利な機能として、キャピタライズ(先頭だけを大文字にする)があります。
#highlight(lisp) {{
;; 一文字目を大文字に、残りは全て小文字にする
(capitalize "The cat in the hat") ;=> "The Cat In The Hat"
(capitalize "THE 77TH-HATTED CAT") ;=> "The 77th-Hatted Cat"
;; 一文字目を大文字に、残りは何もしない
(upcase-initials "The cat in the hat") ;=> "The Cat In The Hat"
(upcase-initials "THE 77TH-HATTED CAT") ;=> "THE 77TH-HATTED CAT" }}
** 大文字と小文字の入れ替え
#highlight(lisp) {{
(require 'cl)
(let ((case-fold-search nil))
(map 'string
#'(lambda (c)
(if (char-equal (upcase c) c)
(downcase c)
(upcase c)))
"i lOVE eMACS."))
;=> "I Love Emacs." }}
** コマンドの実行結果を文字列に設定する
#highlight(lisp) {{
(shell-command-to-string "file -ib /bin/bash") ;=> "application/x-executable\n" }}
** 複数行の文字列を作成する
** ヒアドキュメントの終端文字列をインデントする
** 複数行のコマンドの実行結果を文字列に設定する
** 部分文字列を取り出す
&italic(){(substring string START &optional END)}
substring関数を使います。
startは先頭の添え字、endは終端の添え字を表します(endは含めずにコピーする)。
#highlight(lisp) {{
; 0(a)から、3(d)なので"abc"を生成
(substring "abcdefg" 0 3) ;=> "abc"
; 負の添え字は逆から数える
(substring "abcdefg" -3 -1) ;=> "ef"
; 第2引数は省略可能で、終端までコピーを表す
(substring "abcdefg" 2) ;=> "cdefg"
; 先頭に0を渡すと文字列のコピーと等価になる
(substring "abcdefg" 0) ;=> "abcdefg" }}
** 部分文字列を置き換える
CLライブラリのsetfマクロとsubstring関数を使います。この場合は変数の中身が破壊されます。
#highlight(lisp) {{
(require 'cl)
(setq s "Apple Banana Orange")
(setf (substring s 0 5) "Vine") ;=> "Vine"
s ;=> "Vine Banana Orange" }}
** 文字列を指定されたパターンで分割する
Rubyのsplitとほぼ同じように使えます、第2引数に渡すのは正規表現です。
デフォルトでは空白文字を区切り文字として扱います。
&italic(){(split-string STRING &optional SEPARATORS OMIT-NULLS)}
#highlight(lisp) {{
(split-string "Soup is good food" "o") ;=> ("S" "up is g" "" "d f" "" "d")
(split-string "Soup is good food" "o+") ;=> ("S" "up is g" "d f" "d")
(split-string "Soup is good food") ;=> ("Soup" "is" "good" "food") }}
** 文字列中の式を評価し値を展開する
** 文字列中の環境変数を展開する
#highlight(lisp) {{
(substitute-in-file-name "LANG=${LANG}") ;=> "LANG=ja_JP.UTF-8" }}
** 文字列を1文字ずつ処理する
色々な方法があると思いますが、map関数を利用すると以下のように書けます。
以下のサンプルはstr変数の内容を1文字ずつ、*Messages*バッファに出力します。
#highlight(lisp) {{
(require 'cl)
(setq str "a b c d\n** ** ** *\n123\n456\n")
(map nil '(lambda (x) (message x)) (split-string str ""))
;=> *Messages*
;a
;
;b
;
;c
;
;d
; [2 times]
;* [7 times]
; [2 times]
;1
;2
;3
; [2 times]
;4
;5
;6
; [2 times] }}
** 文字列を1行ずつ処理する
色々な方法があると思いますが、map関数を利用すると以下のように書けます。
以下のサンプルはstr変数の内容を1行ずつ、*Messages*バッファに出力します。
#highlight(lisp) {{
(setq str "a b c d\n** ** ** *\n123\n456\n")
(map nil '(lambda (x) (message x)) (split-string str "\n"))
;=> *Messages*
;a b c d
;** ** ** *
;123
;456 }}
** 文字列の先頭と末尾の空白文字を削除する
もうちょっといい方法無いかなー。
#highlight(lisp) {{
(car (split-string (car (cdr (split-string " abcd " "^ +"))) " +$")) ;=> "abcd"
; 正規表現を使ってみる
(replace-regexp-in-string "^\\s-+\\|\\s-+$" "" " \t abc def \t ") ;=> "abc def" }}
** 文字列を数値に変換する (to_i)
string-to-number関数を使います。基数を指定することもできます。
&italic(){(string-to-number STRING &optional BASE)}
#highlight(lisp) {{
(string-to-number "256") ;=> 256
(string-to-number "256.0") ;=> 256.0
(string-to-number "-256.5") ;=> -256.5
;; 基数を指定する
(string-to-number "110") ;=> 110
(string-to-number "110" 8) ;=> 72 (#o110)
(string-to-number "110" 16) ;=> 272 (#x110) }}
** 数値を文字列に変換する (to_s)
string-to-numberの逆の関数、number-to-string関数を使います。
#highlight(lisp) {{
(number-to-string 256) ;=> "256"
(number-to-string -256.0) ;=> "-256.0"
(number-to-string -256.5) ;=> "-256.5" }}
** 文字列を浮動小数点に変換する (to_f)
number-to-string関数は浮動小数にも使えます。
#highlight(lisp) {{
(string-to-number "10.1") ;=> 10.1 }}
** 8進文字列を整数に変換する (oct)
** 16進文字列を整数に変換する (hex)
** ASCII文字をコード値に(コード値をASCII文字に)変換する
** 文字列を中央寄せ・左詰・右詰する
#highlight(lisp){{
;; 左詰め
(format "%10s" "foo") ;=> " foo"
(format "%10d" 1234) ;=> " 1234"
;; 右詰め
(format "%-10s" "foo") ;=> "foo "
(format "%-10d" 1234) ;=> "1234 " }}
** "次"の文字列を取得する
** 文字列を暗号化する
** 文字列中で指定したパターンにマッチする部分を置換する
&italic(){(replace-regexp-in-string REGEXP REP STRING &optional FIXEDCASE LITERAL SUBEXP START)}
#highlight(lisp) {{
(setq s "Apple Banana Apple Orange")
(replace-regexp-in-string "Apple" "Pine" s) ;=> "Pine Banana Pine Orange" }}
** 文字列中に含まれている任意文字列の位置を求める
#highlight(lisp) {{
(setq s "Apple Banana Apple Orange")
(string-match "Apple" s) ;=> 0
(string-match "Banana" s) ;=> 6 }}
** 文字列の末端の改行を削除する
#highlight(lisp) {{
replace-regexp-in-string "\n+$" "" STRING) }}
** カンマ区切りの文字列を扱う
#highlight(lisp) {{
(split-string "001,TAKEUCHI Hitoshi,Yokohama" ",") ;=> ("001" "TAKEUCHI Hitoshi" "Yokohama") }}
** 任意のパターンにマッチするものを全て抜き出す
** 漢字コードを変換する
#highlight(lisp) {{
; エンコード
(encode-coding-string "漢字です" 'sjis)
(encode-coding-string "漢字です" 'euc-jp)
(encode-coding-string "漢字です" 'utf-8)
(encode-coding-string "漢字です" 'emacs-mule)
; デコード
(decode-coding-string (encode-coding-string "漢字です" 'utf-8) 'utf-8)
;=> "漢字です" }}
** マルチバイト文字の数を数える
** マルチバイト文字列の最後の1文字を削除する
** printf整形
#highlight(lisp) {{
(format "このバッファは %s." (buffer-name)) ;=> "このバッファは *scratch*."
;整数 %d
(format "%d" 100) ;=> "100"
;浮動小数点その1 %f
(format "%f" 100.0) ;=> "100.000000"
;浮動小数点その2 %g できるだけ短くなる出力にする
(format "%g" 100.00) ;=> "100"
(format "%g" 100.05) ;=> "100.05"
(format "%g" 1000000000000000) ;=> "1e+015"
(format "%g" 0.00000000000000000001) ;=> "1e-020"
;ダブルクォートなどをエスケープして出力
(format "この文字列 %S のダブルクォートなどはエスケープされる" "test")
;=> "この文字列 \"test\" のダブルクォートなどはエスケープされる"
(format "この文字列 %S のダブルクォートなどはエスケープされる" "\"test\"")
;=> "この文字列 \"\\\"test\\\"\" のダブルクォートなどはエスケープされる"}}