正则表达式组在单个语句中匹配和替换

时间:2014-04-23 15:32:33

标签: regex scala

我正在使用代码生成工具,我需要像这样转换方法调用(它是java):

public MyObjectType MyObjectType(){

进入更多java-fied版本:

public MyObjectType myObjectType(){

我有这个Scala代码的工作片段可以做到这一点:

val pattern = """[\s]+public[\s]+[\w]+[\s]+([\w]+\(\))\{""".r

val tmp = pattern.findAllIn(s).matchData map { m =>
  val x = m.group(1).replaceAll("\\(\\)", "\\\\(\\\\)")
  s.replaceAll(x, firstLowerCase(x))
}
// if there is no match, return unmodified string,
// otherwise return the only match
val converted = if (tmp.isEmpty) s else tmp.next()

其中s是一行代码,可能是转换的候选者。

函数firstLowerCase定义为:

def firstLowerCase(s: String): String = {
  val (first, rest) = s.splitAt(1)
  first.toLowerCase + rest
}

上面的代码工作正常,但我想知道是否有可能将其缩小(理想情况下是单个模式匹配语句),例如,通过(某种方式)删除()的显式转换\(\),进行匹配并一次性更换或在替换中加入上述功能。我不是一名正则表达式专家,所以也许这个问题太多了。想法?

2 个答案:

答案 0 :(得分:4)

试试这个:

val pattern = """(public\s+\w+\s+)(\w)(?=\w*\(\)\{)""".r
val converted = pattern.replaceAllIn(s, m => m.group(1) + m.group(2).toLowerCase)

replaceAllIn无需执行findAllIn,然后返回并执行replaceAll。我们匹配模式的开头部分,我们需要小写的字符,然后用前瞻断言来处理其余部分(我们不需要替换它,只确认它存在)。替换文本是模式的开头,单个字符为小写,firstLowerCase不需要。

答案 1 :(得分:1)

这似乎正在做你需要的。我也使这种模式更加灵活,例如在{之前允许空格。

import scala.util.matching.Regex

// wingedsubmariner's answer actually has a better pattern
val Pattern = """(public\s+\w+\s+)(\w+)(\s*\(\)\s*\{)""".r

def firstLowerCase(s: String): String = {
  val (first, rest) = s.splitAt(1)
  first.toLowerCase + rest
}

val lines = List(
  "public MyObjectType MyObjectTypeMeth(){",
  " public MyObjectType MyObjectTypeMeth(){   ",
  "public MyObjectType MyObjectTypeMeth() {",
  "public MyObjectType MyObjectTypeMeth () {")

lines.foreach { s =>
  val converted = Pattern.replaceAllIn(s, m => {
    m.group(1) + firstLowerCase(m.group(2)) + m.group(3)
  })

  println(converted)
}

<强>输出:

public MyObjectType myObjectTypeMeth(){
 public MyObjectType myObjectTypeMeth(){   
public MyObjectType myObjectTypeMeth() {
public MyObjectType myObjectTypeMeth () {