Kotlin の正規表現は Regex クラスで扱います。Regex("""\d+""") でパターンを作り、全体が一致するかは matches、一部に含まれるかは containsMatchIn、取り出しは find / findAll、置き換えは replace、分割は split を使います。

この記事では、9つの関数の戻り値と用途を一覧にし、全体一致と部分一致の取り違え、グループの取り出し方3種類、ラムダ置換、$ のエスケープ、RegexOption、raw 文字列の書き分け、パターンの書き間違いで出る例外までを、すべて実行した出力と一緒に示します。

確認環境:Ubuntu 24.04 / Kotlin 2.4.20(kotlinc、JVM 向け)/ OpenJDK 21.0.10。Kotlin/JVM の Regex は java.util.regex を土台にしているため、例外文は Java のものが表示されます。

Kotlin Regex の早見表

関数 戻り値 一致の範囲 用途
matches(input) Boolean 全体 入力チェック(形式が合っているか)
matchEntire(input) MatchResult? 全体 入力チェックをしつつ、グループも取り出す
matchAt(input, index) MatchResult? 指定位置から 文字列の途中の決まった位置で一致を調べる(Kotlin 1.7 から)
containsMatchIn(input) Boolean 部分 含まれているかを調べる
find(input) MatchResult? 部分(最初の1件) 最初の一致を取り出す
findAll(input) MatchResult の Sequence 部分(すべて) 一致をすべて取り出す
replace(input, replacement) String 部分(すべて) すべて置き換える。ラムダも渡せる
replaceFirst(input, replacement) String 部分(最初の1件) 最初の1件だけ置き換える
split(input) String の List 部分(すべて) 一致した箇所を区切りにして分ける
MatchResult から取り出すもの 書き方 中身
一致した文字列 m.value String
位置 m.range IntRange
グループ(リスト) m.groupValues[1] String。0 番は全体。一致しなかったグループは空文字
グループ(変数へ分ける) val (a, b) = m.destructured 1 番から順に入る
名前付きグループ m.groups["name"]?.value 一致しなかったグループは null

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Kotlin 正規表現 Regexの使い方 find・replace」

まず動かす:9つの関数を同じ文字列で試す

fun main() {
    val re = Regex("""\d+""")          // 数字が1個以上
    val text = "注文A-120、注文B-45"

    println(re.matches("120"))                 // 全体が一致するか
    println(re.matches(text))
    println(re.containsMatchIn(text))          // 一部でも一致するか
    println(re.find(text)?.value)              // 最初の一致
    println(re.findAll(text).map { it.value }.toList())  // すべての一致
    println(re.replace(text, "#"))             // すべて置換
    println(re.replaceFirst(text, "#"))        // 最初だけ置換
    println(re.split(text))                    // 一致した箇所で分割
    println(re.matchEntire("120")?.value)      // 全体一致の MatchResult
    println(re.matchEntire(text)?.value)
    println(re.matchAt(text, 4)?.value)        // 指定した位置から一致するか
    println(re.matchAt(text, 0)?.value)
    println(re.matchesAt(text, 4))
}
kotlinc overview.kt -include-runtime -d overview.jar
java -Dstdout.encoding=UTF-8 -jar overview.jar

-Dstdout.encoding=UTF-8 は、日本語の出力を UTF-8 で表示するための指定です。

true
false
true
120
[120, 45]
注文A-#、注文B-#
注文A-#、注文B-45
[注文A-, 、注文B-, ]
120
null
120
null
true

matchAt は「その位置からちょうど一致が始まるか」を調べます。4文字目(0 始まり)は 1 なので一致し、0文字目は「注」なので null です。Boolean だけほしいときは matchesAt を使います。split の結果の最後が空文字なのは、文字列の末尾が一致で終わっているためです。

全体一致と部分一致の取り違えを出力で確かめる

入力チェックでよくあるつまずきが、全体一致(matches)のつもりで部分一致(containsMatchIn)を使うことです。

fun main() {
    val digits = Regex("""\d{3}""")   // 数字3桁
    val inputs = listOf("123", "1234", "abc123", "12")

    println("入力      matches  containsMatchIn  matchEntire  find")
    for (s in inputs) {
        println(
            "%-9s %-8s %-16s %-12s %s".format(
                s,
                digits.matches(s),
                digits.containsMatchIn(s),
                digits.matchEntire(s)?.value,
                digits.find(s)?.value,
            )
        )
    }

    // String 側の関数でも同じ区別がある
    println("1234".matches(digits))      // 全体一致
    println("1234".contains(digits))     // 部分一致
    println(digits in "1234")            // contains と同じ意味

    // 入力チェックを部分一致で書くと通ってしまう例
    val code = Regex("""[A-Z]{2}-\d{4}""")
    val input = "xxAB-12345yy"
    println("containsMatchIn: " + code.containsMatchIn(input))
    println("matches        : " + code.matches(input))
    // ^ と $ を付ければ containsMatchIn でも全体一致の意味になる
    println("^...$ + contains: " + Regex("""^[A-Z]{2}-\d{4}$""").containsMatchIn(input))
}
入力      matches  containsMatchIn  matchEntire  find
123       true     true             123          123
1234      false    true             null         123
abc123    false    true             null         123
12        false    false            null         null
false
true
true
containsMatchIn: true
matches        : false
^...$ + contains: false

「数字3桁」のパターンに対して、1234 や abc123 は containsMatchIn だと true になります。形式のチェックには matches か matchEntire を使います。 文字列側から書く場合は、"1234".matches(regex) が全体一致、"1234".contains(regex) と regex in "1234" が部分一致です。

目的 Regex 側 String 側
全体が形式どおりか re.matches(s) / re.matchEntire(s) s.matches(re)
一部に含まれるか re.containsMatchIn(s) s.contains(re) / re in s

グループの取り出し:groupValues・destructured・名前付き

丸かっこで囲んだ部分(グループ)は、3つの方法で取り出せます。

fun main() {
    val re = Regex("""(\d{4})-(\d{2})-(\d{2})""")
    val m = re.find("公開日: 2026-10-05 更新")!!

    // groupValues:0 番が全体、1 番からが丸かっこの中身
    println(m.value)
    println(m.groupValues)
    println(m.groupValues[1] + "年")
    println(m.range)

    // destructured:グループを順に変数へ(全体は含まない)
    val (year, month, day) = m.destructured
    println("$year / $month / $day")

    // 名前付きグループ:(?<名前>...) と groups["名前"]
    val named = Regex("""(?<user>[\w.]+)@(?<domain>[\w.]+)""")
    val nm = named.find("連絡先 taro.yamada@example.com まで")!!
    println(nm.groups["user"]?.value)
    println(nm.groups["domain"]?.value)
    println(nm.groups[1]?.value + " " + nm.groups[1]?.range)

    // 一致しなかった省略可能なグループ
    val opt = Regex("""(\d+)(px|em)?""")
    val om = opt.find("幅 120")!!
    println(om.groupValues)          // 一致しなかったグループは空文字
    println(om.groups[2])            // groups では null

    // findAll と組み合わせて全部取り出す
    val pairs = Regex("""(\w+)=(\d+)""")
        .findAll("apple=120, banana=80, cherry=300")
        .map { it.groupValues[1] to it.groupValues[2].toInt() }
        .toMap()
    println(pairs)

    // 無い名前を指定するとエラーになる
    try {
        nm.groups["host"]
    } catch (e: Exception) {
        println("${e::class.qualifiedName}: ${e.message}")
    }
    // 見つからないときの find は null
    println(re.find("日付なし"))
}
2026-10-05
[2026-10-05, 2026, 10, 05]
2026年
5..14
2026 / 10 / 05
taro.yamada
example.com
taro.yamada 4..14
[120, 120, ]
null
{apple=120, banana=80, cherry=300}
java.lang.IllegalArgumentException: No group with name <host>
null
方法 向く場面 気をつける点
groupValues[n] グループが1〜2個で、手早く取りたい 0 番は一致全体。一致しなかったグループは空文字
destructured グループを全部、名前を付けた変数で受けたい 全体は含まれず 1 番から。変数の数はグループの数以内にする(超えると IndexOutOfBoundsException)
groups["name"] グループが多い、あとからパターンを直す可能性がある 戻り値は MatchGroup? なので ?.value。パターンに無い名前は IllegalArgumentException

find は一致が無いと null を返します。上のコードでは説明を短くするために !! を使っていますが、入力が決まっていない場面では ?. や ?: return で null を受けます。

置換:文字列・グループ参照・ラムダ

fun main() {
    val text = "apple 120円, banana 80円"

    // 文字列で置換
    println(Regex("""\d+""").replace(text, "N"))
    println(Regex("""\d+""").replaceFirst(text, "N"))

    // グループ参照:$1 / ${name}
    println(Regex("""(\w+) (\d+)円""").replace(text, "$2円の$1"))
    println(Regex("""(?<name>\w+) (?<price>\d+)円""").replace(text, "\${price}:\${name}"))

    // ラムダ置換:一致ごとに計算して置き換える
    println(Regex("""\d+""").replace(text) { m -> (m.value.toInt() * 2).toString() })
    println(Regex("""\b[a-z]""").replace(text) { it.value.uppercase() })
    println(Regex("""(\w+) (\d+)円""").replace(text) { m ->
        val (name, price) = m.destructured
        "$name=${"%,d".format(price.toInt() * 100)}"
    })

    // 置換後の文字列に $ をそのまま入れたいとき
    try {
        println(Regex("""\d+円""").replace(text, "$ 5"))
    } catch (e: Exception) {
        println("${e::class.qualifiedName}: ${e.message}")
    }
    println(Regex("""\d+円""").replace(text, "\\$5"))
    println(Regex("""\d+円""").replace(text, Regex.escapeReplacement("$5")))
    println(Regex("""\d+円""").replace(text) { "$5" })   // ラムダの戻り値はそのまま使われる

    // パターン側の記号をそのまま探したいとき
    println(Regex("1+1").containsMatchIn("1+1=2"))
    println(Regex(Regex.escape("1+1")).containsMatchIn("1+1=2"))
    println(Regex.escape("1+1"))
    println(Regex.fromLiteral("a.b").containsMatchIn("axb") to Regex("a.b").containsMatchIn("axb"))

    // String.replace は第1引数が String なら正規表現ではなく文字そのもの
    println("a.b.c".replace(".", "-"))
    println("a.b.c".replace(Regex("."), "-"))
}
apple N円, banana N円
apple N円, banana 80円
120円のapple, 80円のbanana
120:apple, 80:banana
apple 240円, banana 160円
Apple 120円, Banana 80円
apple=12,000, banana=8,000
java.lang.IllegalArgumentException: Illegal group reference
apple $5, banana $5
apple $5, banana $5
apple $5, banana $5
false
true
\Q1+1\E
(false, true)
a-b-c
-----

置換のポイント

  • 置換後の文字列では $1 や ${name} がグループの参照になります。 Kotlin の通常の文字列では ${...} が文字列テンプレートとして先に働くので、名前付きの参照は "\${price}" のように $ の前へバックスラッシュを置きます。"$2円の$1" のように $ の直後が数字の場合は、テンプレートにならずそのまま渡ります。
  • 計算して置き換えるときはラムダを渡します。 ラムダは MatchResult を受け取り、戻り値がそのまま置換後の文字列になります。
  • 置換後に $ という文字そのものを入れたいときは、"\\$5" と書くか、Regex.escapeReplacement("$5") を通すか、ラムダで返します。そのまま "$ 5" を渡すと Illegal group reference になります。
  • パターン側で記号をそのまま探したいときは Regex.escape("1+1") か Regex.fromLiteral("a.b") を使います。
  • String.replace は、第1引数が String なら正規表現として扱いません。 "a.b.c".replace(".", "-") は a-b-c、replace(Regex("."), "-") は全部の文字が置き換わって ----- になります。

分割:split

fun main() {
    println(Regex("""\s*,\s*""").split("apple , banana,cherry ,  melon"))
    println(Regex("""\s+""").split("  a  b   c "))
    println("  a  b   c ".trim().split(Regex("""\s+""")))
    println(Regex(",").split("a,b,c,d", limit = 2))
    println(Regex("""[,;/]""").split("a,b;c/d"))
    println(Regex("""(?<=\d)(?=[a-z])""").split("12ab34cd"))
    println(Regex(",").splitToSequence("a,b,c").map { it.uppercase() }.toList())
}
[apple, banana, cherry, melon]
[, a, b, c, ]
[a, b, c]
[a, b,c,d]
[a, b, c, d]
[12, ab34, cd]
[A, B, C]

前後に空白がある文字列を \s+ で分けると、先頭と末尾に空文字が入ります。 先に trim() しておくと要素だけが残ります。limit は分ける個数の上限で、2 を渡すと最初の区切りだけで分かれます。

RegexOption の一覧

fun main() {
    for (o in RegexOption.entries) println("${o.name} value=${o.value} mask=${o.mask}")

    val text = "Kotlin\nkotlin regex\nJAVA"

    println(Regex("kotlin").findAll(text).count())
    println(Regex("kotlin", RegexOption.IGNORE_CASE).findAll(text).count())

    println(Regex("^[a-zA-Z]+$").findAll(text).map { it.value }.toList())
    println(Regex("^[a-zA-Z]+$", RegexOption.MULTILINE).findAll(text).map { it.value }.toList())

    println(Regex("Kotlin.kotlin").containsMatchIn(text))
    println(Regex("Kotlin.kotlin", RegexOption.DOT_MATCHES_ALL).containsMatchIn(text))

    val commented = Regex(
        """
        (\d{3})   # 前半3桁
        -         # 区切り
        (\d{4})   # 後半4桁
        """,
        RegexOption.COMMENTS,
    )
    println(commented.find("番号 123-4567")?.groupValues)

    println(Regex("a.c", RegexOption.LITERAL).containsMatchIn("abc") to Regex("a.c", RegexOption.LITERAL).containsMatchIn("a.c"))

    // 複数指定は Set で渡す。パターンの中に (?i) と書く方法もある
    val both = Regex("^java$", setOf(RegexOption.IGNORE_CASE, RegexOption.MULTILINE))
    println(both.find(text)?.value)
    println(Regex("(?im)^java$").find(text)?.value)
    println(both.options)
}
IGNORE_CASE value=2 mask=2
MULTILINE value=8 mask=8
LITERAL value=16 mask=16
UNIX_LINES value=1 mask=1
COMMENTS value=4 mask=4
DOT_MATCHES_ALL value=32 mask=32
CANON_EQ value=128 mask=128
1
2
[]
[Kotlin, JAVA]
false
true
[123-4567, 123, 4567]
(false, true)
JAVA
JAVA
[IGNORE_CASE, MULTILINE]
RegexOption 働き パターン内の書き方
IGNORE_CASE 大文字と小文字を区別しない (?i)
MULTILINE ^ と $ が各行の先頭と末尾に一致する (?m)
DOT_MATCHES_ALL . が改行にも一致する (?s)
COMMENTS パターンの中に空白と # から始まるコメントを書ける (?x)
LITERAL パターン全体を文字そのものとして扱う Regex.fromLiteral でも同じ
UNIX_LINES 行の区切りを \n だけにする (?d)
CANON_EQ 正準分解で等しい文字を同じとみなす なし

公式の API リファレンスによると、IGNORE_CASE と MULTILINE はすべての対象(JVM・JS・Native・Wasm)で使え、残りの5つは JS を除く対象で使えます。複数指定するときは setOf(...) で渡します。

raw 文字列と通常文字列の書き分け

fun main() {
    // 通常の文字列:バックスラッシュを2つ重ねる
    val normal = Regex("\\d+\\.\\d+")
    // raw 文字列(""" で囲む):バックスラッシュは1つでよい
    val raw = Regex("""\d+\.\d+""")
    // toRegex() でも作れる
    val ext = """\d+\.\d+""".toRegex()

    println(normal.pattern)
    println(raw.pattern)
    println(normal.pattern == raw.pattern)
    println(ext.find("値は 3.14 です")?.value)

    // バックスラッシュそのものを探す
    val path = """C:\work\memo.txt"""
    println(Regex("\\\\").split(path))      // 通常の文字列では4つ
    println(Regex("""\\""").split(path))    // raw 文字列では2つ

    // raw 文字列の中でも $ は文字列テンプレートとして働く
    val unit = "円"
    println(Regex("""\d+$unit""").find("120円")?.value)
    // 行末の $ は、後ろに名前が続かなければそのまま書ける
    println(Regex("""^\d+$""").matches("120"))
    // $ の後ろに英字が続く形をそのまま書きたいときは ${'$'}
    println(Regex("""\${'$'}price""").pattern)
    println(Regex("""\${'$'}price""").containsMatchIn("単価は \$price です"))

    // raw 文字列の中に " を書く
    println(Regex("""name="(\w+)"""").find("""<input name="email">""")?.groupValues?.get(1))
}
\d+\.\d+
\d+\.\d+
true
3.14
[C:, work, memo.txt]
[C:, work, memo.txt]
120円
true
\$price
true
email
書きたいもの 通常の文字列 "..." raw 文字列 """..."""
数字 \d "\\d" """\d"""
ピリオドそのもの "\\." """\."""
バックスラッシュそのもの "\\\\" """\\"""
行末の $ "$"(後ろに名前が続かなければそのまま) 同じ
$ の後ろに英字が続く形 "\\\$price" """\${'$'}price"""
ダブルクォート "\"" そのまま書ける

正規表現は raw 文字列で書くと、バックスラッシュを重ねずに済み、パターンがそのまま読めます。 raw 文字列でも $unit のような文字列テンプレートは働くので、変数を埋め込むこともできます。変数の中身を文字そのものとして扱いたいときは Regex.escape(変数) を通してから埋め込みます。

パターンの書き間違いで出る PatternSyntaxException

パターンの文法に誤りがあると、Regex を作る時点で java.util.regex.PatternSyntaxException が出ます。メッセージには、説明・位置・パターン・位置を指す ^ が含まれます。

import java.util.regex.PatternSyntaxException

fun tryRegex(pattern: String) {
    try {
        Regex(pattern)
        println("OK: $pattern")
    } catch (e: PatternSyntaxException) {
        println("--- $pattern ---")
        println(e.message)
        println("description=${e.description} index=${e.index}")
    }
}

fun main() {
    tryRegex("""(\d+""")        // かっこが閉じていない
    tryRegex("""[a-z""")        // 角かっこが閉じていない
    tryRegex("""*abc""")        // 繰り返しの記号が先頭にある
    tryRegex("""a{2,1}""")      // 回数の範囲が逆
    tryRegex("""\""")           // バックスラッシュで終わっている
    tryRegex("""(?<1st>\d)""")  // グループ名が数字で始まる
    tryRegex("""\d+)""")        // 閉じかっこだけがある
    tryRegex("""\d{3}-\d{4}""") // 正しいパターン
}
--- (\d+ ---
Unclosed group near index 4
(\d+
description=Unclosed group index=4
--- [a-z ---
Unclosed character class near index 3
[a-z
   ^
description=Unclosed character class index=3
--- *abc ---
Dangling meta character '*' near index 0
*abc
^
description=Dangling meta character '*' index=0
--- a{2,1} ---
Illegal repetition range near index 5
a{2,1}
     ^
description=Illegal repetition range index=5
--- \ ---
Unescaped trailing backslash near index 1
\
description=Unescaped trailing backslash index=1
--- (?<1st>\d) ---
capturing group name does not start with a Latin letter near index 3
(?<1st>\d)
   ^
description=capturing group name does not start with a Latin letter index=3
--- \d+) ---
Unmatched closing ')' near index 2
\d+)
  ^
description=Unmatched closing ')' index=2
OK: \d{3}-\d{4}
メッセージ 原因 直し方
Unclosed group 丸かっこが閉じていない 閉じかっこを足す。かっこを文字として探すなら \(
Unclosed character class 角かっこが閉じていない ] を足す。文字として探すなら \[
Dangling meta character 繰り返しの記号の前に対象が無い 前に文字を置く。記号そのものなら \ を前に付ける
Illegal repetition range {2,1} のように範囲が逆 小さい数を先に書く
Unescaped trailing backslash パターンがバックスラッシュ1つで終わっている \\ と2つ書く
capturing group name does not start with a Latin letter グループ名が数字で始まっている 英字で始まる名前にする
Unmatched closing ')' 閉じかっこだけがある 開きかっこを足すか \) にする

利用者が入力した文字列からパターンを作る場合は、try / catch で PatternSyntaxException を受けるか、Regex.escape で文字そのものとして扱います。

応用:入力チェックとログの分解

// 何度も使う Regex はトップレベルや companion object に置いて1回だけ作る
private val POSTAL = Regex("""\d{3}-\d{4}""")
private val HEX_COLOR = Regex("""#[0-9a-fA-F]{6}""")
private val LOG_LINE = Regex("""(?<time>\d{2}:\d{2}:\d{2}) \[(?<level>[A-Z]+)] (?<msg>.*)""")

fun main() {
    println(listOf("123-4567", "1234567", "123-45678").map { it to POSTAL.matches(it) })
    println(listOf("#1a2B3c", "#12345", "#gggggg").map { it to HEX_COLOR.matches(it) })

    val logs = listOf(
        "12:00:01 [INFO] started",
        "12:00:05 [ERROR] connection refused",
        "壊れた行",
    )
    for (line in logs) {
        val m = LOG_LINE.matchEntire(line)
        if (m == null) {
            println("形式が違う行: $line")
            continue
        }
        println("${m.groups["level"]!!.value} @ ${m.groups["time"]!!.value}: ${m.groups["msg"]!!.value}")
    }

    // when と組み合わせる
    fun kind(s: String) = when {
        POSTAL.matches(s) -> "郵便番号"
        HEX_COLOR.matches(s) -> "色コード"
        else -> "その他"
    }
    println(listOf("123-4567", "#ffffff", "abc").map(::kind))
}
[(123-4567, true), (1234567, false), (123-45678, false)]
[(#1a2B3c, true), (#12345, false), (#gggggg, false)]
INFO @ 12:00:01: started
ERROR @ 12:00:05: connection refused
形式が違う行: 壊れた行
[郵便番号, 色コード, その他]

Regex のオブジェクトは作るときにパターンの解析が走ります。繰り返し使うパターンは、ループの中で毎回作らず、トップレベルの val や companion object に置いて使い回します。 matchEntire は「形式の確認」と「グループの取り出し」を1回で済ませられるので、1行ずつのログやコードの分解に向いています。

よくある質問

Q. matches と containsMatchIn はどう使い分けますか? A. 文字列全体が形式どおりかを調べるなら matches、どこかに含まれていればよいなら containsMatchIn です。入力チェックに containsMatchIn を使うと、前後に余分な文字があっても true になります。

Q. find と findAll の戻り値は何ですか? A. find は最初の一致を表す MatchResult(無ければ null)、findAll は MatchResult の Sequence です。文字列のリストがほしいときは findAll(text).map { it.value }.toList() と書きます。

Q. Regex("...") と "...".toRegex() に違いはありますか? A. 同じパターンの Regex ができます。変数に入っている文字列から作るときは toRegex()、その場で書くときは Regex(...) と使い分けると読みやすくなります。

Q. 大文字と小文字を区別せずに探すには? A. Regex("kotlin", RegexOption.IGNORE_CASE) と書くか、パターンの先頭に (?i) を付けます。複数のオプションは setOf(RegexOption.IGNORE_CASE, RegexOption.MULTILINE) のように Set で渡します。

まとめ

  • 全体一致は matches / matchEntire、部分一致は containsMatchIn / find / findAll。入力チェックには全体一致を使います。
  • グループは groupValues(0 番が全体)・destructured(1 番から変数へ)・groups["name"](名前付き)の3通りで取り出せます。
  • replace にはラムダを渡せます。置換後の文字列で $ を文字として使うときは Regex.escapeReplacement かラムダが確実です。
  • split で前後に空文字が出るときは trim() を先に行います。
  • RegexOption は7種類。IGNORE_CASE・MULTILINE・DOT_MATCHES_ALL・COMMENTS がよく使われます。
  • パターンは raw 文字列("""...""")で書くと、バックスラッシュを重ねずに済みます。
  • 文法の誤りは PatternSyntaxException。メッセージの near index と ^ が位置を示します。

参考・出典

  • Kotlin 標準ライブラリ API リファレンス Regex(各関数の定義・戻り値・対応バージョン): https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-regex/
  • Kotlin 標準ライブラリ API リファレンス RegexOption(オプションの説明と対象プラットフォーム): https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-regex-option/

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Kotlin 正規表現 Regexの使い方 find・replace」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?