5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

FortranAdvent Calendar 2021

Day 17

Fortranの標準ライブラリstdlibの紹介(文字・文字列操作)

Last updated at Posted at 2021-12-16

概要

Fortran-langコミュニティが主導して開発しているFortraの標準ライブラリstdlibについて紹介します.紹介する内容は,stdlibの現行バージョン0.1.0に基づいています.

本記事では,stdlibに実装されている文字・文字列操作や定数について説明します.

stdlib_ascii

stdlib_asciiモジュールでは,文字の定数,一文字に対する検査用の手続,文字列を変換する手続が実装されています.

定数

下記の定数が定義されています.

  • ASCIIの各制御文字
    • NUL: Null
    • SOH: ヘッディング開始
    • STX: テキスト開始
    • ETX: テキスト終端
    • EOT: 伝送終了
    • ENQ: 問い合わせ
    • ACK: 肯定応答
    • BEL: ベル
    • BS: 後退
    • TAB: 水平タブ
    • LF: 改行
    • VT: 垂直タブ
    • FF: 書式送り
    • CR: 復帰
    • SO: シフトアウト
    • SI: シフトイン
    • DLE: 伝送制御拡張
    • DC1: 装置制御1
    • DC2: 装置制御2
    • DC3: 装置制御3
    • DC4: 装置制御4
    • NAK: 否定応答
    • SYN: 同期信号
    • ETB: 伝送ブロック終結
    • CAN: 取り消し
    • EM: 媒体終結
    • SUB: 置換
    • ESC: 拡張
    • FS: ファイル分離
    • GS: グループ分離
    • RS: レコード分離
    • US: ユニット分離
    • DEL: 抹消
  • digits: 数字
    "0123456789"
  • octal_digits: 8進数に用いられる数字
    "01234567"
  • fullhex_digit, hex_digits, lowerhex_digits: 16進数に用いられる数字
    "0123456789ABCDEFabcdef", "0123456789ABCDEF", "0123456789abcdef"
  • letters: アルファベット
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  • uppercase, lowercase: アルファベットの大文字,小文字
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz"
  • whitespace: ASCIIの空白
    " ", TAB, VT, CR, LF, FF

文字の検査用手続

文字がアルファベットか等を検査する手続がいくつか定義されています.

  • is_alpha
    文字がアルファベットであれば.true.,そうでなければ.false.を返す.
  • is_alphanum
    文字がアルファベットか数字であれば.true.,そうでなければ.false.を返す.
  • is_digit
    文字が数字であれば.true.,そうでなければ.false.を返す.
  • is_hex_digit
    文字が16進数に使う数字・文字であれば.true.,そうでなければ.false.を返す.
  • is_octal_digit
    文字が8進数に使う数字であれば.true.,そうでなければ.false.を返す.
  • is_control
    文字がASCIIの制御文字であれば.true.,そうでなければ.false.を返す.
  • is_white
    文字がホワイトスペースに類する文字(スペース,水平タブ,垂直タブ, 書式送り,復帰,改行)であれば.true.,そうでなければ.false.を返す.
  • is_blank
    文字がブランク文字(スペース,水平タブ)であれば.true.,そうでなければ.false.を返す.
  • is_ascii
    文字がアスキー文字(文字コード0x00から0x7F)であれば.true.,そうでなければ.false.を返す.
  • is_punctuation
    文字が句読文字であれば.true.,そうでなければ.false.を返す.
  • is_graphical
    文字が空白以外の印字可能文字であれば.true.,そうでなければ.false.を返す.
  • is_printable
    文字が空白も含む印字可能文字であれば.true.,そうでなければ.false.を返す.
  • is_lower
    文字が小文字アルファベットであれば.true.,そうでなければ.false.を返す.
  • is_upper
    文字が大文字アルファベットであれば.true.,そうでなければ.false.を返す.

使用例

is_alphanum

! 文字がアルファベットもしくは数字かを判別する.
print *, "A is alphabet or number :", is_alphanum("A") ! T
print *, "a is alphabet or number :", is_alphanum("a") ! T
print *, "1 is alphabet or number :", is_alphanum("1") ! T
print *, "# is alphabet or number :", is_alphanum("#") ! F
print *, "á is alphabet or number :", is_alphanum("á") ! F

is_alpha

! 文字がアルファベットかを判別する.
print *, "A is alphabet :", is_alpha("A") ! T
print *, "A is alphabet :", is_alpha("a") ! T
print *, "1 is alphabet :", is_alpha("1") ! F
print *, "# is alphabet :", is_alpha("#") ! F
print *, "á is alphabet :", is_alpha("á") ! F

is_lower

! 文字が小文字アルファベットかを判別する.
print *, "A is lowercase alphabet :", is_lower("A") ! F
print *, "a is lowercase alphabet :", is_lower("a") ! T
print *, "1 is lowercase alphabet :", is_lower("1") ! F
print *, "# is lowercase alphabet :", is_lower("#") ! F
print *, "á is lowercase alphabet :", is_lower("á") ! F

is_upper

! 文字が大文字アルファベットかを判別する.
print *, "A is uppercase alphabet :", is_upper("A") ! T
print *, "a is uppercase alphabet :", is_upper("a") ! F
print *, "1 is uppercase alphabet :", is_upper("1") ! F
print *, "# is uppercase alphabet :", is_upper("#") ! F
print *, "á is uppercase alphabet :", is_upper("á") ! F

is_digit

! 文字が数字かを判別する.
print *, "A is digit :", is_digit("A") ! F
print *, "a is digit :", is_digit("a") ! F
print *, "1 is digit :", is_digit("1") ! T

is_octal_digit

! 文字が8進数で使われる数字かを判別する.
print *, "A is octal digit :", is_octal_digit("A") ! F
print *, "a is octal digit :", is_octal_digit("a") ! F
print *, "7 is octal digit :", is_octal_digit("7") ! T
print *, "8 is octal digit :", is_octal_digit("8") ! F

is_hex_digit

! 文字が16進数で使われる数字・文字かを判別する.
print *, "A is hex digit :", is_hex_digit("A") ! T
print *, "a is hex digit :", is_hex_digit("a") ! T
print *, "F is hex digit :", is_hex_digit("F") ! T
print *, "G is hex digit :", is_hex_digit("G") ! F
print *, "8 is hex digit :", is_hex_digit("8") ! T

is_white

! 文字がホワイトスペースかを判別する.
! スペース,水平タブ,垂直タブ, 書式送り,復帰,改行のとき真
print *, "' ' is white space :", is_white(" ") ! T
print *, "NUL is white space :", is_white(NUL) ! F
print *, "TAB is white space :", is_white(TAB) ! T
print *, "LF is white space :", is_white(LF) ! T
print *, "VT is white space :", is_white(VT) ! T
print *, "FF is white space :", is_white(FF) ! T
print *, "CR is white space :", is_white(CR) ! T
print *, "A is white space :", is_white("A") ! F

is_blank

! 文字がブランク文字かを判別する.
! スペース,水平タブとき真.
print *, "' ' is blank :", is_blank(" ") ! T
print *, "NUL is blank :", is_blank(NUL) ! F
print *, "TAB is blank :", is_blank(TAB) ! T
print *, "LF is blank :", is_blank(LF) ! F
print *, "VT is blank :", is_blank(VT) ! F
print *, "FF is blank :", is_blank(FF) ! F
print *, "CR is blank :", is_blank(CR) ! F
print *, "A is blank :", is_blank("A") ! F

is_control

! 文字が制御文字かを判別する.
print *, "' ' is control character :", is_control(" ") ! F
print *, "NUL is control character :", is_control(NUL) ! T
print *, "TAB is control character :", is_control(TAB) ! T
print *, "LF is control character :", is_control(LF) ! T
print *, "VT is control character :", is_control(VT) ! T
print *, "FF is control character :", is_control(FF) ! T
print *, "CR is control character :", is_control(CR) ! T
print *, "DEL is control character :", is_control(DEL) ! T
print *, "A is control character :", is_control("A") ! F

is_punctuation

! 文字が句読文字かを判別する.
print *, ", is punctuation character :", is_punctuation(",") ! T
print *, ". is punctuation character :", is_punctuation(".") ! T
print *, ": is punctuation character :", is_punctuation(":") ! T
print *, "; is punctuation character :", is_punctuation(";") ! T
print *, "! is punctuation character :", is_punctuation("!") ! T
print *, "# is punctuation character :", is_punctuation("#") ! T
print *, "~ is punctuation character :", is_punctuation("~") ! T
print *, "+ is punctuation character :", is_punctuation("+") ! T
print *, "_ is punctuation character :", is_punctuation("_") ! T
print *, "' ' is punctuation character :", is_punctuation(" ") ! F
print *, "A is punctuation character :", is_punctuation("A") ! F
print *, "1 is punctuation character :", is_punctuation("1") ! F
print *, "TAB is punctuation character :", is_punctuation(TAB) ! F

文字列の変換手続

文字列の大文字,小文字を変換する手続,反転する手続が定義されています.

  • to_lower
    大文字アルファベットを小文字に変換する.
  • to_upper
    小文字アルファベットを大文字に変換する.
  • to_title
    各英単語の最初の一文字を大文字にする.単語が引用符などで囲まれている場合でも,最初の単語を大文字にする.最初が数字の場合は何もしない.
  • to_sentence
    文字列の最初の一文字を大文字にする.
  • reverse
    文字列を反転する.

使用例

to_upper, to_lower

use :: stdlib_ascii

! 大文字アルファベットを小文字に変換する.
print *, uppercase
print *, to_lower(uppercase)
! ABCDEFGHIJKLMNOPQRSTUVWXYZ
! abcdefghijklmnopqrstuvwxyz

! 小文字アルファベットを大文字に変換する.
print *, lowercase
print *, to_upper(lowercase)
! abcdefghijklmnopqrstuvwxyz
! ABCDEFGHIJKLMNOPQRSTUVWXYZ

to_title, to_sentence, reverse

use :: stdlib_ascii

character(*), parameter :: str = "hello there. this is 'enquated string'. 19th century writer"

! 各英単語の最初の一文字を大文字にする.
print *, to_title(str)
! Hello There. This Is 'Enquated String'. 19th Century Writer

! 文字列の最初の一文字を大文字にする.
print *, to_sentence(str)
! Hello there. this is 'enquated string'. 19th century writer

! 文字列を反転する.
print *, reverse(str)
! retirw yrutnec ht91 .'gnirts detauqne' si siht .ereht olleh

stdlib_strings

stdlib_stringsモジュールでは,文字列を操作する手続が実装されています.

文字列の操作手続

  • strip
    文字列前後の空白を削除する.
  • chomp
    文字列の末尾から指定した文字を削除する.文字を指定しない場合は空白が削除される.
  • starts_with
    文字列が部分文字列から始まっているかを判別.
  • ends_with
    文字列が部分文字列で終わっているかを判別.
  • slice
    文字列を取り出す.
  • find
    文字列内に部分文字列パターンが含まれている場合にその開始位置を返す.
  • replace_all
    文字列から部分文字列を別の文字列に置き換える.
  • padl
    指定の文字数になるように左側に文字を詰める.
  • padr
    指定の文字数になるように右側に文字を詰める.
  • count
    文字列に含まれる部分文字列の数を数える.
  • to_string
    整数,実数,複素数,論理値を文字に変換する.

使用例

strip

print '(A)', "|"//strip("   hello   ")//"|"
! |hello|

! whitespaceは全て削除する.
print '(A)', "|"//strip(" "//TAB//LF//VT//FF//CR)//"|"
! ||

! 文字列の先頭が空白でない場合は,whitespaceを削除しない.
print '(A)', "|"//strip("'"//TAB//LF//VT//FF//CR//"'")//"|"
! |'
! '|

chomp

! 文字を指定しない場合は空白が削除される.
print '(A)', "|"//chomp("   hello   ")//"|"
! |   hello|

! 文字列からlとoを削除する.
print '(A)', "|"//chomp("hello", set=["l", "o"])//"|"
! |he|

! lとoが末尾にないので変化しない.
print '(A)', "|"//chomp("   hello   ", set=["l", "o"])//"|"
! |   hello   |

! l, o, " "が末尾にあるので削除される.
print '(A)', "|"//chomp("   hello   ", set=["l", "o", " "])//"|"
! |   he|

! loが末尾にあるので削除される.
print '(A)', "|"//chomp("hello", substring="lo")//"|"
! |hel|

starts_with, ends_with

print *, "hello starts with hel: ", starts_with("hello", "hel")
! hello starts with hel: T

print *, "hello starts with lo: ", starts_with("hello", "lo")
! hello starts with lo: F

print *, "hello ends with hel: ", ends_with("hello", "hel")
! hello ends with hel: F

print *, "hello ends with lo: ", ends_with("hello", "lo")
! hello ends with lo: T

slice

! 先頭から末尾まで間隔2で文字列を取り出す.
print '(A)', slice("1234567890", stride=2)
! 13579

! 2文字目から末尾まで間隔2で文字列を取り出す.
print '(A)', slice("1234567890", first=2, stride=2)
! 24680

! 先頭から4文字目まで間隔2で文字列を取り出す.
print '(A)', slice("1234567890", last=4, stride=2)
! 13

! 3文字目から9文字目まで間隔4で文字列を取り出す.
print '(A)', slice("1234567890", first=3, last=9, stride=4)
! 37

replace_all

! ingをedに置き換える.
print '(A)', replace_all("functions for string handling", pattern="ing", replacement="ed")
! functions for stred handled

! wwを12に置き換える.
print '(A)', replace_all("wwwwww", "ww", "12")
! 121212

! "  "を" "に置き換える.オーバーラップはしない.
print '(A)', "|"//replace_all("      ", "  ", " ")//"|"
! |   |

padl, padr

! 10文字になるように左側に空白を詰める.
print '(A)', "|"//padl("string", 10)//"|"
! |    string|

! 10文字になるように左側に指定の文字を詰める.
print '(A)', "|"//padl("string", 10, "-")//"|"
! |----string|

! 指定の文字数が元の文字数より小さい場合は何もしない.
print '(A)', "|"//padl("string", 4, "-")//"|"
! |string|

! 10文字になるように右側に空白を詰める.
print '(A)', "|"//padr("string", 10)//"|"
! |string    |

! 10文字になるように右側に指定の文字を詰める.
print '(A)', "|"//padr("string", 10, "-")//"|"
! |string----|

! 指定の文字数が元の文字数より小さい場合は何もしない.
print '(A)', "|"//padr("string", 4, "-")//"|"
! |string|

count

! iの数を数える.
print *, count("functions for string handling", "i")
! 3

! ingの数を数える.
print *, count("functions for string handling", "ing")
! 2

! i, n, oの数を数える.
print *, count("functions for string handling", ["i", "n", "o"])
! [3, 5, 2]

! "  "の数を数える.オーバーラップを許容し,1,2文字目,2,3文字目・・・の数を返す.
print *, count("      ", "  ")
! 5

! "  "の数を数える.引数でオーバーラップを許容することを明示する.
print *, count("      ", "  ", consider_overlapping=.true.)
! 5

! "  "の数を数える.オーバーラップを許容しない.
! 1,2文字目がカウントされたら,次は2,3文字目ではなく3,4文字目をカウントする.
print *, count("      ", "  ", consider_overlapping=.false.)
! 3

to_string

! 整数を文字に変換する.
print *, to_string( huge(0)) ! 2147483647
print *, to_string(-huge(0)) ! -2147483647

! 書式付きで整数を文字に変換する
! 4桁の数として文字列に変換する.
print *, "|"//to_string(1, '(I4)')   ! |   1

! 4桁でゼロ埋めして文字列に変換する.
print *, "|"//to_string(1, '(I4.4)') ! |0001

! 2桁の数として文字に変換する.桁数が足りない場合は*に置き換えられる.
print *, to_string(100, '(I2)') ! **

block
    integer(int32) :: i
    i = 16
    ! 2桁の10進数として文字列に変換.
    print *, to_string(i, '(I2)') ! 16

    ! 8桁の2進数として文字列に変換.
    print *, to_string(i, '(B8.8)') ! 00010000

    ! 2桁の16進数として文字列に変換.
    print *, to_string(i, '(Z2)') ! 10
end block
! 実数を文字列に変換する.
print *, to_string( huge(0.)) ! 0.340282347E+39
print *, to_string(-huge(0.)) ! -0.340282347E+39

print *, to_string(1.) ! 1.00000000

! 書式付きで実数を文字列に変換する.
! 全体で8文字,浮動小数点以下を3桁として文字列に変換する.
print '(A,F8.3)', to_string(100., '(F8.3)'), 100. ! 100.000 100.000

! 指数表記で文字列に変換する.
print '(A,E10.2e2)', to_string(1000., '(E10.2e2)'), 1000. ! 0.10E+04  0.10E+04

! 科学表記で文字列に変換する.

print '(A,ES10.2)', to_string(1000., '(ES10.2)'), 1000. ! 1.00E+03  1.00E+03
! 論理型を文字列に変換する.

! 偽を文字列に変換する.
print *, to_string(.false.) ! F

! 真を文字列に変換する.

print *, to_string(.true.) ! T

! 書式付きで文字列に変換する.
print *, to_string(.true., '(L3)') !   T

! 誤った書式で文字列に変換すると,[*]に置き換えられる.
print *, to_string(.true., '(I3)') ! [*]
! 複素数を文字列に変換する.
complex(real64) :: c
c = cmplx(0.75, 0.25)

! 書式付きで複素数を文字列に変換する.
print *, to_string(c, '(F6.2)')!  (  0.75,  0.25)

! 複素数リテラルを文字列に変換する.
print *, to_string((0.5, 0.5))! (0.500000000,0.500000000)

! 書式付きで複素数リテラルを文字列に変換する.
print *, to_string((0.5, 0.5), '(F8.3)')! (   0.500,   0.500)
end block
5
1
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
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?