8

スカラで機能的な方法で文字列に対していくつかの順序付けられた連続したreplaceAll(...、...)を実行したいと思います。

最もエレガントなソリューションは何ですか?Scalazようこそ!;)

4

5 に答える 5

15

呼び出しが数回しかない場合は、それらをチェーンします。そうでなければ私はこれを試してみると思います:

Seq("a" -> "b", "b" -> "a").foldLeft("abab"){case (z, (s,r)) => z.replaceAll(s, r)}

または、紛らわしいワイルドカードと余分なクロージャを含む短いコードが好きな場合:

Seq("a" -> "b", "b" -> "a").foldLeft("abab"){_.replaceAll _ tupled(_)}
于 2012-07-05T18:23:00.650 に答える
13

まず、replaceAllメソッドから関数を取得しましょう。

scala> val replace = (from: String, to: String) => (_:String).replaceAll(from, to)
replace: (String, String) => String => java.lang.String = <function2>

これで、scalazで定義さFunctorれた関数のインスタンスを使用できます。このようにして、を使用して(またはユニコードエイリアスを使用して見栄えを良くするために)関数を作成できます。map

次のようになります。

scala> replace("from", "to") ∘ replace("to", "from") ∘ replace("some", "none")
res0: String => java.lang.String = <function1>

ハスケルウェイ作曲(右から左)を好む場合は、以下を使用してcontramapください。

scala> replace("some", "none") ∙ replace("to", "from") ∙ replace ("from", "to")
res2: String => java.lang.String = <function1>

Category インスタンスを楽しむこともできます:

scala> replace("from", "to") ⋙ replace("to", "from") ⋙ replace("some", "none")
res5: String => java.lang.String = <function1>

scala> replace("some", "none") ⋘ replace("to", "from") ⋘ replace ("from", "to")
res7: String => java.lang.String = <function1>

そしてそれを適用する:

scala> "somestringfromto" |> res0
res3: java.lang.String = nonestringfromfrom

scala> res2("somestringfromto")
res4: java.lang.String = nonestringfromfrom

scala> "somestringfromto" |> res5
res6: java.lang.String = nonestringfromfrom

scala> res7("somestringfromto")
res8: java.lang.String = nonestringfromfrom
于 2012-07-06T07:40:33.610 に答える
4

この問題に対する別のScalazベースの解決策は、Endoモノイドを使用することです。このモノイドは、恒等関数(モノイドの単位元として)と関数合成(モノイドの追加操作として)をキャプチャします。このソリューションは、適用する関数の任意のサイズの(場合によっては空の)リストがある場合に特に役立ちます。

val replace = (from: String, to: String) => (_:String).replaceAll(from, to)

val f: Endo[String] = List(
  replace("some", "none"),
  replace("to", "from"),
  replace("from", "to")    
).foldMap(_.endo)

例(フォロンの例の1つを使用)

scala> f.run("somestringfromto")
res0: String = nonestringfromfrom
于 2013-03-11T12:14:36.337 に答える
3

匿名パラメーターを使用して置換関数を定義すると、連続する置換関数をチェーン化できます。

scala> val s = "hello world"
res0: java.lang.String = hello world

scala> def replace = s.replaceAll(_, _)
replace: (java.lang.String, java.lang.String) => java.lang.String

scala> replace("h", "H")  replace("w", "W")
res1: java.lang.String = Hello World
于 2012-07-05T17:47:32.707 に答える
-1
#to replace or remove multiple substrings in scala in dataframe's string column

import play.api.libs.json._
#to find
def isContainingContent(str:String,regexStr:String):Boolean={
  val regex=new scala.util.matching.Regex(regexStr)
  val containingRemovables= regex.findFirstIn(str)
  containingRemovables match{
    case Some(s) => true
    case None => false
  }
}
val colContentPresent= udf((str: String,regex:String) => {
  isContainingContent(str,regex)
})
#to remove
val cleanPayloadOfRemovableContent= udf((str: String,regexStr:String) => {
  val regex=new scala.util.matching.Regex(regexStr)
  val cleanedStr= regex.replaceAllIn(str,"")
  cleanedStr
})
#to define
val removableContentRegex=
"<log:Logs>[\\s\\S]*?</log:Logs>|\\\\n<![\\s\\S]*?-->|<\\?xml[\\s\\S]*?\\?>"

#to call
val dfPayloadLogPresent = dfXMLCheck.withColumn("logsPresentInit", colContentPresent($"payload",lit(removableContentRegex)))
val dfCleanedXML = dfPayloadLogPresent.withColumn("payload", cleanPayloadOfRemovableContent($"payload",lit(removableContentRegex)))
于 2019-03-06T17:47:07.543 に答える