Scala: сопоставление необязательных групп регулярных выражений

Я пытаюсь сопоставить группу параметров в Scala 2.8 (бета-версия 1) со следующим кодом:

import scala.xml._

val StatementPattern = """([\w\.]+)\s*:\s*([+-])?(\d+)""".r

def buildProperty(input: String): Node = input match {
    case StatementPattern(name, value) => <propertyWithoutSign />
    case StatementPattern(name, sign, value) => <propertyWithSign />
}

val withSign = "property.name: +10"
val withoutSign = "property.name: 10"

buildProperty(withSign)        // <propertyWithSign></propertyWithSign>
buildProperty(withoutSign)     // <propertyWithSign></propertyWithSign>

Но это не работает. Каков правильный способ сопоставления необязательных групп регулярных выражений?


person BefittingTheorem    schedule 17.03.2010    source источник


Ответы (2)


Необязательная группа будет нулевой, если она не соответствует, поэтому вам нужно включить «нуль» в сопоставление с шаблоном:

import scala.xml._

val StatementPattern = """([\w\.]+)\s*:\s*([+-])?(\d+)""".r

def buildProperty(input: String): Node = input match {
    case StatementPattern(name, null, value) => <propertyWithoutSign />
    case StatementPattern(name, sign, value) => <propertyWithSign />
}

val withSign = "property.name: +10"
val withoutSign = "property.name: 10"

buildProperty(withSign)        // <propertyWithSign></propertyWithSign>
buildProperty(withoutSign)     // <propertyWithSign></propertyWithSign>
person BefittingTheorem    schedule 17.03.2010
comment
Scala использует метод Matcher.group в Regex.unapplySeq. Это указывает, что если группе не удается сопоставить часть последовательности, возвращается null — ‹java.sun.com/javase/6/docs/api/java/util/regex/ - person Ben Lings; 17.03.2010
comment
Было бы неплохо, если бы Scala могла использовать класс Option для необязательного поля регулярного выражения, а не требовать проверки нуля. - person Rob Wilton; 07.11.2014
comment
Порядок case statements имеет значение: операторы, соответствующие null, должны быть перечислены первыми, иначе переменная sign будет содержать null. - person dr jerry; 29.01.2019

Я не вижу никаких проблем с вашим регулярным выражением. Хотя вам не нужно избегать . в классе char.

РЕДАКТИРОВАТЬ:

Вы можете попробовать что-то вроде:

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

Чтобы зафиксировать имя и значение, где значение может иметь необязательный знак.

person codaddict    schedule 17.03.2010
comment
@codaddict спасибо, что указали на это;) С регулярным выражением все в порядке, проблема в том, что я не вижу, кому сопоставить необязательную группу, используя систему сопоставления шаблонов Scala. И я не могу найти примеры, чтобы сделать это в сети - person BefittingTheorem; 17.03.2010
comment
@codaaddict Спасибо, это заставит мой код работать, но вопрос сопоставления шаблонов Scala все еще остается :) Мне действительно нужен другой XML в зависимости от того, есть ли знак или нет, поэтому используйте систему сопоставления шаблонов для извлечения и проверки, есть ли это знак кажется мне самым чистым решением - person BefittingTheorem; 17.03.2010