UWSCRの組み込み関数：文字列操作系

文字列操作系組み込み関数の変更点および新規追加された関数の解説です。

# 変更点

## replace

正規表現を用いた置換ができるようになりました。第四引数を`TRUE`にすることで第二引数を正規表現として扱います。

```php
// [a-z]にマッチする文字を削除する
print replace("あabcいdうefえgお", "[a-z]", "", TRUE) // あいうえお
```

正規表現モードの場合は置換後文字列に`$0`を記述しておくとマッチした文字列に置き換わります。グループマッチの場合`$1`以降がサブマッチした文字列になります。

```php
// \w+ が world にマッチするため $0 は world になる
print replace("world", "\w+", "hello $0!", TRUE)
// hello world!

// [a-z]+ が $1,\d+ が $2 となる
print replace("aa11bb22cc33", "([a-z]+)(\d+)", "$1 = $2, ", TRUE)
// aa = 11, bb = 22, cc = 33,
```

## trim

trim関数の第二引数で除去する文字列を指定できるようになりました。

```php
// e, d, f のいずれかが連続していれば除去する
print trim("edeffededdabcedfffedeeddedf", "edf")
// abc
```

## format

### 数値フォーマットの拡張

16進数(小文字)、2進数にもフォーマットできるようになりました。

```php
// 16進数
print format(42, 0, -1) // 2A
// 16進数(小文字)
print format(42, 0, -2) // 2a
// 2進数
print format(42, 0, -3) // 101010
```

### 埋め指定

数値フォーマット時に指定幅に対する不足をどの様に埋めるかを指定できるようになりました。第四引数にFMT定数で指定できます。

```php
// 通常 FMT_DEFAULT
print "|"+format(42, 8, -1)+"|"            // |      2A|
// 右埋め
print "|"+format(42, 8, -1, FMT_RIGHT)+"|" // |2A      |
// 0埋め
print "|"+format(42, 8, -1, FMT_ZERO) +"|" // |0000002A|
// 右0埋め
print "|"+format(42, 8, -1, FMT_ZEROR)+"|" // |2A000000|
```

### 日時フォーマット

gettime関数の戻り値を日時フォーマット文字列を使って任意の書式にフォーマットできるようになりました。

```php
timestamp = gettime(, "2023/04/01 10:10:10")
print format(timestamp, "%c") 
// 2023年04月01日 10時10分10秒

// ミリ秒にも対応
timestamp_ms = timestamp * 1000 + 234
print format(timestamp_ms, "%+", TRUE)
// 2023-04-01T10:10:10.234+09:00
```

## encode/decode

UTF8バイト配列に対応しました。`CODE_BYTEARRAYU`定数を指定します。

```php
str = "あいうえお"

bytes = encode(str, CODE_BYTEARRAYU)
print bytes
// [227, 129, 130, 227, 129, 132, 227, 129, 134, 227, 129, 136, 227, 129, 138]

print decode(bytes, CODE_BYTEARRAYU)
// あいうえお
```

UWSCRでは以下の定数が無視され、入力値がそのまま返ります。

- `CODE_ANSI`
- `CODE_UTF8`


# 新規

## lengthu

文字列のUTF8バイト数を得ます。

```php
str = "あいうえお"
print length(str)  // 5
print lengthu(str) // 15
```

## lengthw

NULL終端Unicode(ワイド)文字列としての長さを得ます。長さとはword配列長で、末尾のNULL文字も含めた数を返します。

```php
str = "あいうえお"
print length(str)  // 5
print lengthw(str) // 6
```

## 正規表現

### NewRE

正規表現オブジェクトを返します。`replace`関数の第二引数に正規表現オブジェクトを渡した場合は必ず正規表現モードでの置換が行われます。

```php
// 1. 正規表現
// 2. case sensitiveにするならTRUE
// 3. 複数行を対象とするならTRUE、その場合 ^ と $ が各行で使える
// 4. TRUEなら . が \n にマッチするようになる
re = newre("([a-z]+)(\d+)", FALSE, FALSE, FALSE)
print re // regex: (?i)([a-z]+)(\d+)
// 第四引数のは無視され必ず正規表現モードで置換する
print replace("aa11bb22cc33", re, "$1 = $2, ", FALSE)
// aa = 11, bb = 22, cc = 33,
```

### TestRE

正規表現がマッチするかどうかを真偽値で返します。正規表現は文字列か正規表現オブジェクトを渡します。

```php
str = "あいAうえお"
// case sensitiveなのでマッチしない
print testre(str, "[a-z]") // False

// 正規表現オブジェクトを使いcase insensitiveでテスト
re = newre("[a-z]", FALSE)
print testre(str, re) // True
```

### Match

正規表現にマッチする文字列のリストを返します。正規表現は文字列か正規表現オブジェクトを渡します。

```php
str = "aa11bb22cc33"
// マッチした文字列を配列で返す
for matched in match(str, "[a-z]+")
    print matched
next
// aa
// bb
// cc

// グループマッチの場合マッチした文字列とサブマッチの配列として返す
for matches in match(str, "([a-z]+)(\d+)")
    print matches
next
// [aa11, aa, 11]
// [bb22, bb, 22]
// [cc33, cc, 33]
```

### RegEx

正規表現を使ったさまざまな文字列操作ができる関数です。正規表現は文字列か正規表現オブジェクトを渡します。

```php
str = "aa11bb22cc33"
re = newre("([a-z]+)(\d+)")

// REGEX_TESTの場合はTestRE関数と同等
print regex(str, re, REGEX_TEST)
// True

// REGEX_MATCHはMatch関数と同等
for matches in regex(str, re, REGEX_MATCH)
    print matches
next 
// [aa11, aa, 11]
// [bb22, bb, 22]
// [cc33, cc, 33]

// 定数ではなく文字列を渡した場合はreplace関数(正規表現モード)と同等
print regex(str, re, "$1 = $2, ")
// aa = 11, bb = 22, cc = 33,
```

## JSONとUObject

UObjectとjson文字列の相互互換のための組み込み関数です。

### FromJson

json文字列をUObjectに変換します。

```php
textblock json
{
    "foo": 1,
    "bar": 2
}
endtextblock

obj = fromjson(json)
print obj.foo // 1
```

## ToJson

UObjectをjson文字列に変換します。

```php
obj = @{
    "foo": 1,
    "bar": {
        "baz": 2
    }
}@

print tojson(obj)
// {"bar":{"baz":2},"foo":1}

// 整形する
print tojson(obj, TRUE)
// {
//   "bar": {
//     "baz": 2
//   },
//   "foo": 1
// }

// 子オブジェクトも変換可能
print tojson(obj.bar)
// {"baz": 2}
```