LoginSignup
12
9

More than 5 years have passed since last update.

Emacs用文字列操作ライブラリ s.el の使い方

Last updated at Posted at 2017-09-03

Emacs用文字列操作ライブラリ s.el の使い方の練習です。
自分用およびRuby脳な人にもわかりやすいように Ruby だとどんな感じになるかも合わせて書いています。

左スペース除去 (s-trim-left)

EmacsLisp
(s-trim-left " a ")    ; => "a "
Ruby
" a ".lstrip    # => "a "

右スペース除去 (s-trim-right)

EmacsLisp
(s-trim-right " a ")    ; => " a"
Ruby
" a ".rstrip    # => " a"

左右スペース除去 (s-trim)

EmacsLisp
(s-trim " a ")    ; => "a"
Ruby
" a ".strip    # => "a"

2つ以上のスペースを1つに置換 (s-collapse-whitespace)

EmacsLisp
(s-collapse-whitespace "  a  b  c  ")    ; => " a b c "
Ruby
"  a  b  c  ".squeeze(" ")    # => " a b c "

区切り文字で分割 (s-split)

EmacsLisp
(s-split "," "a,b,c")    ; => ("a" "b" "c")
Ruby
"a,b,c".split(/,/)    # => ["a", "b", "c"]

区切り文字でN個だけ分割 (s-split-up-to)

EmacsLisp
(s-split-up-to "," "a,b,c" 1)    ; => ("a" "b,c")
Ruby
"a,b,c".split(/,/, 2)    # => ["a", "b,c"]

行毎に分割 (s-lines)

EmacsLisp
(s-lines "a\nb\nc")    ; => ("a" "b" "c")
Ruby
"a\nb\nc".split(/\n/)    # => ["a", "b", "c"]

区切り文字を間に入れて結合 (s-join)

EmacsLisp
(s-join "," '("a" "b" "c"))    ; => "a,b,c"
Ruby
["a", "b", "c"].join(",")    # => "a,b,c"

文字列の結合 (s-concat)

EmacsLisp
(s-concat "a" "b" "c")    ; => "abc"
Ruby
"a" "b" "c"    # => "abc"

前に結合 (s-prepend)

EmacsLisp
(s-prepend "_" "foo")    ; => "_foo"
Ruby
"_" + "foo"    # => "_foo"

後ろに結合 (s-append)

EmacsLisp
(s-append "_" "foo")    ; => "foo_"
Ruby
"foo" + "_"    # => "foo_"

文字列の繰り返し (s-repeat)

EmacsLisp
(s-repeat 3 "a")    ; => "aaa"
Ruby
"a" * 3    # => "aaa"

プレフィクス除去 (s-chop-prefix)

EmacsLisp
(s-chop-prefix "a" "ax")    ; => "x"
Ruby
"ax".sub(/\Aa/, "")    # => "x"

複数のプレフィクス除去 (s-chop-prefixes)

EmacsLisp
(s-chop-prefixes '("a" "b") "abx")    ; => "x"
Ruby
["a", "b"].inject("abx") { |a, e| a.sub(/\A#{e}/, "") }    # => "x"

サフィックス除去 (s-chop-suffix)

EmacsLisp
(s-chop-suffix "a" "xa")    ; => "x"
Ruby
"xa".sub(/a\z/, "")    # => "x"

複数のサフィックス除去 (s-chop-suffixes)

EmacsLisp
(s-chop-suffixes '("a" "b") "xba")    ; => "x"
Ruby
["a", "b"].inject("xba") { |a, e| a.sub(/#{e}\z/, "") }    # => "x"

共通のプレフィクスを抽出 (s-shared-start)

EmacsLisp
(s-shared-start "axb" "ayb")    ; => "a"
Ruby
a = "axb"
b = "ayb"
it = b.each_char
i = a.chars.find_index { |e| e != it.next }
i ? a[0...i] : ""    # => "a"

共通のサフィックスを抽出 (s-shared-end)

EmacsLisp
(s-shared-end "axb" "ayb")    ; => "b"
Ruby
a = "axb"
b = "ayb"
it = b.chars.reverse.each
i = a.chars.reverse.find_index { |e| e != it.next }
i ? a.chars.last(i).join : ""    # => "b"

行末の改行除去 (s-chomp)

EmacsLisp
(s-chomp "a\r\n")    ; => "a"
Ruby
"a\r\n".chomp    # => "a"

ちょんぎる (s-truncate)

EmacsLisp
(s-truncate 5 "0123456789")    ; => "01..."
ActiveSupport
"0123456789".truncate(5)    # => "01..."

指定横幅に収まるように整形 (s-word-wrap)

EmacsLisp
(s-word-wrap 4 "a b c")    ; => "a b\nc"
Ruby
require "nkf"
NKF.nkf("-f#{4.pred} -w", "a b c").rstrip    # => "a b\nc"

# マルチバイト未対応だけど
require "action_view"
include ActionView::Helpers::TextHelper
word_wrap("a b c", line_width: 4)    # => "a b\nc"

中央寄せ (s-center)

EmacsLisp
(s-center 5 "a")    ; => "  a  "
Ruby
"a".center(5)    # => "  a  "

左寄せ (s-pad-right)

EmacsLisp
(s-pad-right 5 " " "a")    ; => "a    "
Ruby
"a".ljust(5)    # => "a    "

右寄せ (s-pad-left)

EmacsLisp
(s-pad-left 5 " " "a")    ; => "    a"
Ruby
"a".rjust(5)    # => "    a"

先頭N文字 (s-left)

EmacsLisp
(s-left 2 "012")    ; => "01"
Ruby
"012"[0...2]    # => "01"

後ろのN文字 (s-right)

EmacsLisp
(s-right 2 "012")    ; => "12"
Ruby
"012"[-2..-1]    # => "12"

サフィックス確認 (s-ends-with?)

EmacsLisp
(s-ends-with? "c" "abc")    ; => t
Ruby
"abc".end_with?("c")    # => true

プレフィクス確認 (s-starts-with?)

EmacsLisp
(s-starts-with? "a" "abc")    ; => t
Ruby
"abc".start_with?("a")    # => true

文字列が含まれる? (s-contains?)

EmacsLisp
(s-contains? "b" "abc")    ; => t
Ruby
"abc".include?("b")    # => true

文字列が一致する? (s-equals?)

EmacsLisp
(s-equals? "a" "a")    ; => t
Ruby
"a" == "a"    # => true

文字列をコードの大小で比較 (s-less?)

EmacsLisp
(s-less? "a" "b")    ; => t
Ruby
"a" < "b"    # => true

正規表現がマッチする? (s-matches?)

EmacsLisp
(s-matches? "\\w+" "foo")    ; => t
Ruby
"foo".match?(/\w+/)    # => true

なんもない? (s-blank?)

EmacsLisp
(s-blank? "")    ; => t
ActiveSupport
"".blank?    # => true

なんかある? (s-present?)

EmacsLisp
(s-present? "x")    ; => t
ActiveSupport
"x".present?    # => true

なんかあればそれ (s-presence)

EmacsLisp
(s-presence "x")    ; => "x"
ActiveSupport
"x".presence    # => "x"

全部小文字? (s-lowercase?)

EmacsLisp
(s-lowercase? "foo")    ; => t
Ruby
"foo".match?(/\A[[:lower:]]*\z/)    # => true

全部大文字? (s-uppercase?)

EmacsLisp
(s-uppercase? "FOO")    ; => t
Ruby
"FOO".match?(/\A[[:upper:]]*\z/)    # => true

大文字と小文字の両方含まれる? (s-mixedcase?)

EmacsLisp
(s-mixedcase? "aBc")    ; => t
Ruby
str = "aBc"    # => "aBc"
str.match?(/[[:upper:]]/) && str.match?(/[[:lower:]]/)    # => true

最初だけ大文字? (s-capitalized?)

EmacsLisp
(s-capitalized? "Foo")    ; => t
Ruby
"Foo".match?(/\A[[:upper:]][[:lower:]]/)    # => true

全部数文字? (s-numeric?)

EmacsLisp
(s-numeric? "123")    ; => t
Ruby
"123".match?(/\A\d+\z/)    # => true

文字列置換 (s-replace)

EmacsLisp
(s-replace "a" "x" "abab")    ; => "xbxb"
Ruby
"abab".gsub(/a/, "x")    # => "xbxb"

複数指定できる文字列置換 (s-replace-all)

EmacsLisp
(s-replace-all '(("a" . "x") ("b" . "y")) "abab")    ; => "xyxy"
Ruby
{"a" => "x", "b" => "y"}.inject("abab") { |s, (a, b)| s.gsub(a, b) }    # => "xyxy"

小文字にする (s-downcase)

EmacsLisp
(s-downcase "Foo")    ; => "foo"
Ruby
"Foo".downcase    # => "foo"

大文字にする (s-upcase)

EmacsLisp
(s-upcase "Foo")    ; => "FOO"
Ruby
"Foo".upcase    # => "FOO"

先頭だけ大文字にする (s-capitalize)

EmacsLisp
(s-capitalize "foo_bar")    ; => "Foo_bar"
Ruby
"foo_bar".capitalize    # => "Foo_bar"

単語の先頭を大文字にする (s-titleize)

EmacsLisp
(s-titleize "foo bar")    ; => "Foo Bar"
ActiveSupport
"foo bar".titleize    # => "Foo Bar"

複数の関数を適用 (s-with)

EmacsLisp
(s-with "abc" s-upcase s-reverse)    ; => "CBA"
Ruby
[:upcase, :reverse].reduce("abc", &:send)    # => "CBA"

文字列内の位置を返す (s-index-of)

EmacsLisp
(s-index-of "bc" "abcd")    ; => 1
Ruby
"abcd".index("bc")    # => 1

反転 (s-reverse)

EmacsLisp
(s-reverse "abc")    ; => "cba"
Ruby
"abc".reverse    # => "cba"

複数のマッチした部分を返す (s-match-strings-all)

EmacsLisp
(s-match-strings-all "\\w\\(\\w\\)" "a1 a2")    ; => (("a1" "1") ("a2" "2"))
Ruby
"a1 a2".scan(/(\w(\w+))/)    # => [["a1", "1"], ["a2", "2"]]

マッチした部分を返す (s-match)

EmacsLisp
(s-match "\\w\\(\\w+\\)" "a1 a2")    ; => ("a1" "1")
Ruby
"a1 a2".match(/\w(\w+)/).to_a    # => ["a1", "1"]

マッチした部分の前で分離 (s-slice-at)

EmacsLisp
(s-slice-at "a" "a1a2a3")    ; => ("a1" "a2" "a3")
Ruby
"a1a2a3".split(/(?=a)/)    # => ["a1", "a2", "a3"]

単語っぽいのを拾う (s-split-words)

EmacsLisp
; どんなルールだこれ
(s-split-words "ABCde ABC1 AbCd")    ; => ("AB" "Cde" "AB" "C1" "Ab" "Cd")
Ruby
s = "ABCde ABC1 AbCd"
s = s.gsub(/([[:upper:]])([[:upper:]][\d[:lower:]])/, '\1 \2')    # => "AB Cde AB C1 AbCd"
s = s.gsub(/([[:lower:]])([[:upper:]])/, '\1 \2')    # => "AB Cde AB C1 Ab Cd"
s.split(/[^[:word:]]+/)    # => ["AB", "Cde", "AB", "C1", "Ab", "Cd"]

ローワーキャメルケース化 (s-lower-camel-case)

EmacsLisp
(s-lower-camel-case "foo-bar")    ; => "fooBar"
ActiveSupport
"foo-bar".underscore.camelize(:lower)    # => "fooBar"

アッパーキャメルケース化 (s-upper-camel-case)

EmacsLisp
(s-upper-camel-case "foo-bar")    ; => "FooBar"
ActiveSupport
"foo-bar".underscore.camelize    # => "FooBar"

スネークケース化 (s-snake-case)

EmacsLisp
(s-snake-case "foo-bar")    ; => "foo_bar"
ActiveSupport
"foo-bar".underscore    # => "foo_bar"

ケバブケース化 (s-dashed-words)

EmacsLisp
(s-dashed-words "FooBar")    ; => "foo-bar"
ActiveSupport
"FooBar".underscore.dasherize    # => "foo-bar"

先頭の単語の最初だけ大文字 (s-capitalized-words)

EmacsLisp
(s-capitalized-words "FOO BAR")    ; => "Foo bar"
Ruby
words = "FOO BAR".split(/\s+/)
[words.first.capitalize, words.drop(1).collect(&:downcase)].join(" ")    # => "Foo bar"

単語の先頭だけ大文字 (s-titleized-words)

EmacsLisp
(s-titleized-words "foo bar")    ; => "Foo Bar"
Ruby
"foo bar".split(/\s+/).collect(&:capitalize) * " "    # => "Foo Bar"

先頭の文字だけ集める (s-word-initials)

EmacsLisp
(s-word-initials "foo bar")    ; => "fb"
Ruby
"foo bar".scan(/(\w)\w*/).join    # => "fb"

書式にキーワードを埋めて展開 (s-format)

EmacsLisp
;; alist
(s-format "${a}" 'aget '(("a" . "x") ("b" . "y")))    ; => "x"
;; sequence
(s-format "$0" 'elt ["x" "y"])    ; => "x"
;; hash
(setq v (make-hash-table :test 'equal))
(puthash "a" "x" v)
(puthash "b" "y" v)
(s-format "${a}" 'gethash v)    ; => "x"
Ruby
"%{a}" % {a: "x", b: "y"}    # => "x"
"%1$s" % ["x", "y"]    # => "x"

変数名を埋めて評価 (s-lex-format)

EmacsLisp
(setq a '(1 2 3))
(s-lex-format "a = ${a}")    ; => "a = (1 2 3)"
Ruby
a = [1, 2, 3]
"a = #{a}"    # => "a = [1, 2, 3]"

変数を埋める書式をコードに変換 (s-lex-fmt|expand)

EmacsLisp
(setq a '(1 . 2))    ; => (1 . 2)
(setq v (s-lex-fmt|expand "${a}"))    ; => (s-format "${a}" (quote aget) (list (cons "a" (format (if s-lex-value-as-lisp "%S" "%s") a))))
(eval v)    ; => "(1 . 2)"

マッチした個数を返す (s-count-matches)

EmacsLisp
(s-count-matches "\\w+" "a b c")    ; => 3
Ruby
"a b c".scan(/\w+/).count    # => 3

前後に文字列を追加 (s-wrap)

EmacsLisp
(s-wrap "foo" "(" ")")    ; => "(foo)"
Ruby
"(" + "foo" + ")"    # => "(foo)"
12
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9