生文字列リテラル'contents'#

生文字列リテラルは' 'で囲まれた文字列であり、ほとんどの文字をそのまま解釈します。

文字列 意味
'' '
CRLF LF
CR LF
LF LF
' 生文字列の終端
それ以外の文字 その文字自身

シングルクォートコンテント''#

生文字列内で'を記述するには''と書きます。

$ xa " 'abc''def' "
# abc'def

改行コンテント#

生文字列内には改行を含めることができますが、すべてLFに統一されます。

この性質は、ソースコードの改行コードが変更されてもプログラムの動作が変わらないことを保証します。

$ xa " 'abc
def' "
# abc
# def

文字コンテントabcABC123#

上記を除く文字は書いたとおりに解釈されます。

これは$\も例外ではありません。

$ xa \''abc$def\nop'\'
# abc$def\nop

テンプレート文字列リテラル"contents"#

テンプレート文字列リテラルは" "で囲まれた文字列であり、エスケープや埋め込みなどの機能が使えます。

文字列 意味
\" "
\$ $
\\ \
\t タブ文字
\r CR
\n LF
\xXX 指定したコードポイントU+0000~U+00FFの1文字
\uXXXX 指定したUTF-16のコード単位1個
上記以外の\で始まるシーケンス 構文エラー
CRLF LF
CR LF
LF LF
$識別子や括弧類など 埋め込み
$%フォーマット指定子 括弧類 フォーマット付き埋め込み
" テンプレート文字列の終端
それ以外の文字 その文字自身

エスケープシーケンスコンテント\n#

エスケープシーケンスコンテントは\で始まる一連のシーケンスであり、それぞれ決められた文字を表します。

エスケープシーケンスの一覧は上記の表を参照してください。

\で始まるシーケンスは将来の機能のために予約されており、不正なシーケンスは構文エラーとなります。

$ xa ' "abc\"def\\ghi\njkl" '
# abc"def\ghi
# jkl

Unicodeの1文字を指定するエスケープシーケンス(文字参照)も利用できます。

$ xa ' "\u3042" '
# あ

改行コンテント#

生文字列リテラルの改行コンテントと同様です。

埋め込みコンテント$factor#

$に続いて任意の識別子、リテラル、括弧類を記述でき、その値は文字列化されたうえで文字列に埋め込まれます。

最も一般的な利用形態は、丸括弧によって任意の式を埋め込むことや、単一の識別子を埋め込むことです。

$ xa ' "value is $(100 + 20 + 3)" '
# value is 123

$ xa '
  value := 123
  "value is $value"
'
# value is 123

フォーマット付き埋め込みコンテント$%-+ 07.2f(value)#

フォーマット付き埋め込みコンテントは通常の埋め込みコンテントに似ていますが、以下の点で異なります。

  • $に続いて、%から始まるフォーマット指定子を記述します。
  • 識別子などを直接埋め込むことはできず、括弧類に限られます。
$ xa ' "[$%+09.2f(123)]" '
# [+00123.00]

フォーマット指定子の文法は以下の通りです。

  1. %
  • 必須のマジックワードです。
  1. フラグ(省略可能)
  • 下表のフラグを0個以上指定することができます。
  1. 幅(省略可能)
  • 文字列の長さが幅未満である場合に半角空白で補充します。
  1. .精度(省略可能)
  • 表示する小数の桁数を指定します。
  • 精度が下がる場合、四捨五入が行われます。
  • 切り捨てられる部分が丁度中間の場合、常に絶対値の大きい側に丸められます。
  1. 変換
  • 下表の変換を指定します。
フラグ 意味
- 左揃えにします。
+ 符号を常に表示します。
半角空白 符号のための半角空白を表示します。
0 スペースの代わりに0で埋めます。
変換 意味
d 10進整数
x 16進整数(小文字)
X 16進整数(大文字)
f 10進小数
s 文字列

文字コンテントabcABC123#

上記を除く文字は書いたとおりに解釈されます。

埋め込み文字列リテラル%>contents<%#

埋め込み文字列リテラルは%> <%で囲われた独特な見た目の文字列リテラルです。

文字列 意味
<%% <%
CRLF LF
CR LF
LF LF
<%=%> 埋め込み
<%#%> コメント
<% 埋め込み文字列の終端
それ以外の文字 その文字自身

埋め込み文字列リテラルは、特にHTMLコードの生成と相性がよいです。

$ xa '
  %>
    <table>
      <tr style="color: red;"><th>x</th><th>x×10</th></tr>
      <%= 1 .. 3 | x => %>
        <tr><td><%= x %></td><td><%= x * 10 %></td></tr>
      <% %>
    </table>
  <%
'
#     <table>
#       <tr style="color: red;"><th>x</th><th>x×10</th></tr>
#
#         <tr><td>1</td><td>10</td></tr>
#
#         <tr><td>2</td><td>20</td></tr>
#
#         <tr><td>3</td><td>30</td></tr>
#
#     </table>
xx×10
110
220
330

埋め込み文字列終了シーケンスコンテント<%%#

埋め込み文字列内で<%を記述するには<%%と書きます。

$ xa '%>[ <%% ]<%'
# [ <% ]

改行コンテント#

生文字列リテラルの改行コンテントと同様です。

埋め込みコンテント<%= value %>#

<%= %>で囲うと任意の値を文字列化したうえで埋め込むことができます。

丸括弧と同様、内部で宣言された変数が外部に出ない効果があります。

$ xa ' %>value is <%= 100 + 20 + 3 %><% '
# value is 123

コメントコンテント<%# ... %>#

<%# %>で囲うとコメントになります。コメントの内容は出力されません。

$ xa ' %>hello <%# this is a comment %>world<% '
# hello world

文字コンテントabcABC123#

上記を除く文字は書いたとおりに解釈されます。

文字列の各文字のストリーム化string()#

文字列の各文字を順番にイテレートするストリームを返します。

$ xa '"abc"()'
# a
# b
# c

文字列の要素アクセスstring(index)#

配列と同様、文字列の要素にインデックスでアクセスできます。

$ xa '"abc"(1)'
# b

$ xa '"abc"(-1)'
# c

$ xa '"abc"(2, 0)'
# c
# a

文字列の要素アクセスstring.index#

.演算子で文字列の要素にアクセスできます。

$ xa '"abc".1'
# b

オブジェクトの要素アクセスと同様に、.の右辺を式にすることができます。

$ xa '"abc".(1 + 1)'
# c

添え字が負数であった場合はNULLが返されます。

$ xa '"abc".(-1)'
# NULL

インデックスは数値化されたあと、四捨五入されて評価されます。

$ xa '"abc".("0.95")'
# b

文字列化&value#

前置&演算子は、値の文字列表現を得るのに使います。

$ xa '&[1..3]'
# [1;2;3]

値のタイプごとの文字列表現は以下の通りです。

  • NULLはNULLになります。
  • 整数値の文字列表現は、その整数値の10進数表現になります。
  • TRUEはTRUE、FALSEはFALSEになります。
  • 文字列の文字列表現は、その文字列自身です。
  • 配列の文字列表現は、[1;2;3]のように、;で区切って[ ]で囲んだものです。
  • オブジェクトの文字列表現は、{a:1;b:2}のように、キーと値を:で区切り、そのエントリーを;で区切り、全体を{ }で囲んだものです。

文字列化の実態は、値の&_メソッドを呼び出すことで行われます。

オブジェクトの&_メソッドをオーバーライドすることで、文字列化の処理を変更することができます。

$ xa '&{`&_`: this -> "The value is $(this.value)"}{value: 100}'
# The value is 100

文字列の結合string & string#

文字列の連結を行うには&演算子を使います。

$ xa '"abc" & "def"'
# abcdef

部分文字列の取得#

string[indices]で部分文字列を取得できます。

$ xa '"abcde"[1..3]'
# bcd

先頭・末尾の部分文字列の取得と除去#

STRING::take(count: INT): STRING

STRING::taker(count: INT): STRING

STRING::drop(count: INT): STRING

STRING::dropr(count: INT): STRING

文字列の先頭または末尾の、count文字を取得または除去した文字列を返します。

countは数値化し、四捨五入されます。

各メソッドには同一の動作を持つ別名が存在します。

メソッド 別名 対象 操作 countが文字列の長さを超える場合の動作
take takeFirst 先頭 取得 文字列全体
taker takeLast 末尾 取得 文字列全体
drop dropFirst 先頭 除去 空文字列
dropr dropLast 末尾 除去 空文字列
$ xa '"[" & "abcde"::take(2) & "]"'
# [ab]

$ xa '"[" & "abcde"::taker(2) & "]"'
# [de]

$ xa '"[" & "abcde"::take(0) & "]"'
# []

$ xa '"[" & "abcde"::take(10) & "]"'
# [abcde]

$ xa '"[" & "abcde"::drop(2) & "]"'
# [cde]

$ xa '"[" & "abcde"::dropr(2) & "]"'
# [abc]

$ xa '"[" & "abcde"::drop(0) & "]"'
# [abcde]

$ xa '"[" & "abcde"::drop(10) & "]"'
# []

先頭・末尾の文字の取得#

STRING::first(): STRING | NULL

STRING::last(): STRING | NULL

first lastメソッドで先頭・末尾の1文字を取得します。

文字列が空の場合はNULLを返します。

$ xa '"abcde"::first()'
# a

$ xa '"abcde"::last()'
# e

$ xa '""::first()'
# NULL

$ xa '""::last()'
# NULL

文字列の置換#

STRING::replace(old: STRING | REGEX; new: STRING | (match: VALUE) -> STRING): STRING

STRING::replaceAll(old: STRING | REGEX; new: STRING | (match: VALUE) -> STRING): STRING

STRING::replaceFirst(old: STRING | REGEX; new: STRING | (match: VALUE) -> STRING): STRING

replace replaceAll replaceFirstメソッドで文字列内の置換を行うことができます。

置換対象#

各メソッドの置換対象は以下の通りです。

メソッド 文字列の置換対象 正規表現の置換対象
replace すべての出現個所 グローバルマッチフラグに従う
replaceAll すべての出現個所 すべてのマッチ部分
replaceFirst 最初の出現個所 最初のマッチ部分

文字列による置換#

oldに文字列が渡された場合、その文字列と完全に一致する出現個所を置換します。

文字列版replaceメソッドはreplaceAllメソッドと同じ動作をします。

$ xa '"-ab--ab-"::replace("ab"; "XX")'
# -XX--XX-

$ xa '"-ab--ab-"::replaceAll("ab"; "XX")'
# -XX--XX-

$ xa '"-ab--ab-"::replaceFirst("ab"; "XX")'
# -XX--ab-

正規表現による置換#

oldに正規表現が渡された場合、その正規表現にマッチしたすべての部分を置換します。

正規表現オブジェクトがグローバルでない場合、最初にマッチした部分のみが置換対象となります。

$ xa '"-ab--ab-"::replace(/[a-z]{2}/; "XX")'
# -XX--ab-

$ xa '"-ab--ab-"::replace(/[a-z]{2}/g; "XX")'
# -XX--XX-

replaceAllメソッドとreplaceFirstメソッドは正規表現のグローバルマッチフラグを無視します。

$ xa '"-ab--ab-"::replaceAll(/[a-z]{2}/; "XX")'
# -XX--XX-

$ xa '"-ab--ab-"::replaceAll(/[a-z]{2}/g; "XX")'
# -XX--XX-

$ xa '"-ab--ab-"::replaceFirst(/[a-z]{2}/; "XX")'
# -XX--ab-

$ xa '"-ab--ab-"::replaceFirst(/[a-z]{2}/g; "XX")'
# -XX--ab-

関数への置換#

newに関数が渡された場合、マッチした各部分に対してその関数が呼び出され、その戻り値で置換されます。

$ xa '"-ab--ab-"::replace("ab"; m -> m.0 * 2)'
# -abab--abab-

$ xa '"-ab--ab-"::replace(/[a-z]{2}/g; m -> m.0 * 2)'
# -abab--abab-

文字列ユーティリティ関数#

文字と文字コードの相互変換#

CHAR_CODE(char: STRING): INT

CHAR_CODED(charCode: INT): STRING

CHAR_CODES(string: STRING): STREAM<INT>

CHAR_CODESD(charCodes: STREAM<INT>): STRING

CODE_POINT(char: STRING): INT

CODE_POINTD(codePoint: INT): STRING

CODE_POINTS(string: STRING): STREAM<INT>

CODE_POINTSD(codePoints: STREAM<INT>): STRING

文字列と文字コードを相互に変換します。

CHAR_CODE系はUTF-16コード単位を単位とし、CODE_POINT系はサロゲートペアで表される文字(U+10000以上)を1個のUnicodeコードポイントとして扱います。

末尾にDが付く関数はデコード、付かない関数はエンコードに対応します。

関数 デコード前の型 デコード前の意味 変換方向 デコード後の型 デコード後の意味
CHAR_CODE INT コード単位の数値 ← コード化 STRING 丁度1個のUTF-16コード単位
CHAR_CODED INT コード単位の数値 → 文字列化 STRING 丁度1個のUTF-16コード単位
CHAR_CODES STREAM<INT> 各コード単位の数値 ← コード化 STRING 文字列
CHAR_CODESD STREAM<INT> 各コード単位の数値 → 文字列化 STRING 文字列
CODE_POINT INT コードポイントの数値 ← コード化 STRING 丁度1個のUnicodeコードポイント
CODE_POINTD INT コードポイントの数値 → 文字列化 STRING 丁度1個のUnicodeコードポイント
CODE_POINTS STREAM<INT> 各コードポイントの数値 ← コード化 STRING 文字列
CODE_POINTSD STREAM<INT> 各コードポイントの数値 → 文字列化 STRING 文字列

次のいずれかに該当する入力に対しては、エラーになります。

  • CHAR_CODED CHAR_CODESD: 0以上65535以下でない数値を与えた場合
  • CODE_POINTD CODE_POINTSD: 0以上1114111以下でない数値、またはサロゲートコードポイント(U+D800~U+DFFF)を与えた場合
  • CHAR_CODE CODE_POINT: コード単位またはコードポイントが丁度1個でない文字列を与えた場合
  • CODE_POINT CODE_POINTS: 孤立サロゲートを含む文字列を与えた場合
$ xa 'CHAR_CODE("A")'
# 65

$ xa 'CHAR_CODE("あ")'
# 12354

$ xa 'CHAR_CODED(65)'
# A

$ xa 'CHAR_CODED(12354)'
# あ

$ xa 'CHAR_CODES("ABC🍰") >> JOIN[","]'
# 65,66,67,55356,57200

$ xa 'CHAR_CODESD(65, 66, 67, 55356, 57200)'
# ABC🍰

$ xa '"ABC🍰" >> CHAR_CODES >> CHAR_CODESD'
# ABC🍰

$ xa 'CODE_POINT("A")'
# 65

$ xa 'CODE_POINT("🍰")'
# 127856

$ xa 'CODE_POINTD(65)'
# A

$ xa 'CODE_POINTD(127856)'
# 🍰

$ xa 'CODE_POINTS("ABC🍰") >> JOIN[","]'
# 65,66,67,127856

$ xa 'CODE_POINTSD(65, 66, 67, 127856)'
# ABC🍰

$ xa '"ABC🍰" >> CODE_POINTS >> CODE_POINTSD'
# ABC🍰

UC大文字に変換#

UC(string: STRING): STRING

UC(string: STREAM<STRING>): STREAM<STRING>

引数を文字列化したうえで、大文字に変換します。

ストリームを渡した場合は、各要素を大文字に変換するストリームを返します。

$ xa 'UC("Ab")'
# AB

$ xa '"Ab", "Cd" >> UC'
# AB
# CD

string::UC()で呼び出すことができる拡張関数版もあります。

$ xa '"Ab"::UC()'
# AB

LC小文字に変換#

LC(string: STRING): STRING

LC(string: STREAM<STRING>): STREAM<STRING>

引数を文字列化したうえで、小文字に変換します。

その他の仕様はUCと共通です。

$ xa 'LC("Ab")'
# ab

$ xa '"Ab", "Cd" >> LC'
# ab
# cd

string::LC()で呼び出すことができる拡張関数版もあります。

$ xa '"Ab"::LC()'
# ab

RESOLVEパス解決#

RESOLVE(dir: STRING; file: STRING): STRING

STRING::RESOLVE(file: STRING): STRING

dirを起点にしてfileへのパスを解決します。

$ xa 'RESOLVE("/home/apple"; "Apple.txt")'
# /home/apple/Apple.txt

出力パスは自動で正規化(...の平坦化)が行われます。

シンボリックリンクの解決は行われません。

$ xa 'RESOLVE("/"; "Banana.txt")'
# /Banana.txt

$ xa '"/home/apple/"::RESOLVE("../cherry/./Cherry.txt")'
# /home/cherry/Cherry.txt

"$PWD/file"のような文字列連結を使うと、ルートディレクトリに対して//fileのようなパスが生成されます。

代わりにPWD::RESOLVE("file")のようにRESOLVE関数を使用してください。