본문 바로가기
개발 관련됨/개발 이슈를 해결함

정규표현식에서 알지 못했던 capture group 과 non- capture group

by simplify-len 2022. 6. 6.
val groupMD = """((?:\+|\+-)?[.\d]+)([*/])((?:\+|\+-)?[.\d]+)""".toRegex()

fun foldGroup(v: String): Double = groupMD.findAll(v).fold(0.0) { acc, curr ->
    val (_, left, op, right) = curr.groupValues
    val leftValue = left.replace("+", "").toDouble()
    val rightValue = right.replace("+", "").toDouble()
    val result = when (op) {
        "*" -> leftValue * rightValue
        "/" -> leftValue / rightValue
        else -> throw Throwable("invalid operator $op")
    }
    acc + result
}

 

(...) capture group

(?:...) non- capture group : 그룹은 잡지만, In-memory 에 넣지 않겠어.

(..|..): alternative

? : zero or one = {0, 1} 수량/반복- 있을 수도 있고, 없을 수도 있어. 마치 | 를 한 것과 같아.

+: one or unlimited = {1, }

 

val (_, left, op, right) = curr.groupValues

여기에 잡히는 _ 는 전체이고, left, op, right 는 순서대로 정규표현식에서 캡처링된 결과를 표시한다.

 

val groupMD = """((?:\+|\+-)?[.\d]+)([*/])((?:\+|\+-)?[.\d]+)""".toRegex()

 

?: 가 포함된 정규표현식은 여기를 캡쳐하지 않겠다 라는 의미이다.

 

그러므로 캡쳐하는 그룹은 다음과 같다.

- ((?:\+|\+-)?[.\d]+)

- ([*/])

- ((?:\+|\+-)?[.\d]+)

 

이렇게 3군데서 캡쳐를 하고 이 결과는 left, op, right 순으로 들어간다.

 

만약 ?: 가 없다면 어떻게 될까?

val groupMD = """((\+|\+-)?[.\d]+)([*/])((\+|\+-)?[.\d]+)""".toRegex()

 

캡쳐하는 그룹은 다음과 같다.

- ((\+|\+-)?[.\d]+)

- (\+|\+-)

- ([*/])

 

이렇게 되서 예상과 다른 결과물을 반환할 것이다.

 

 

 

댓글