Scala学习整理[第二十四-二十六章 抽取器和XML]<Programming In Scala>
2017-01-16 15:01
393 查看
第二十四章 抽取器
package SecondWithProgrammingInScala /** * 抽取器 * * 抽取器可以在匹配的同时进行分解 ,可以直接抽出里面的值 * 相当与 is是非语句 + get方法 * 通常配合模式匹配使用 ,在之前章节中匹配并获取数组值 Array(x,y)=> x+y ,也是抽取器 * * 之前的模式匹配和样本类 ,标注了case的样本类可以将参数列表作为匹配项 * 实质就一个语法糖 ,为样本类同时声称了一个伴生对象(同名object) ,并提供了了apply和unapply * 然后模式匹配时候调用unapply ,用于匹配和拆解参数 * * 使用样本类 ,匹配表达式和构造器一致 ,数据和模型是一一对应的 * 使用抽取器 ,可以为一个模型添加不同的抽取方式(对Email字串执行多种方式的抽取) ,数据和模型是分开的 */ object Email { //抽取方法 : 匹配并分解值 def unapply(s: String): Option[(String, String)] = { val parts = s split "@" if (parts.length == 2) Some(parts(0), parts(1)) else None } //注入方法 : 相对的 def apply(user: String, domain: String) = user + "@" + domain } //比较是否是连续的email object TwiceEmail { def unapply(s: String): Option[String] = { val length = s.length / 2 val half = s.substring(0, length) if (half == s.substring(length)) Some(half) else None } } //判断是否全为大写 object UpperCase { //没有设置apply方法 ,在模式匹配时 UpperCase() 是没有参数的 //如果想要利用(输出)匹配到的参数 ,可以使用 str @ UpperCase() def unapply(s: String): Boolean = s.toUpperCase == s } //拆解域名 object Domain { //拆解成seq def unapplySeq(whole: String): Option[Seq[String]] = Some(whole.split("""\.""")) } object ExtractorsApp { //配合模式匹配使用 ,当匹配的是抽取器 ,会自动调用unapply方法获取返回值 def parser(s: String) = { s match { case Email(user, domain) => println(user + " AT " + domain) case _ => print("not an email address") } } def userTwiceUpper(s: String): Unit = { s match { case Email(TwiceEmail(user@UpperCase()), domain) => println("Twice,Upper : " + user + " AT " + domain) case Email(user@UpperCase(), domain) => println("Upper : " + user + " AT " + domain) case Email(TwiceEmail(user), domain) => println("Twice : " + user + " AT " + domain) case Email(user@UpperCase(), domain@UpperCase()) => println("Upper : " + user + " AT " + "Upper : " + domain) case _ => println("not match : " + s) } } def isSinaEmail(s: String): Boolean = s match { case Email(user, Domain("sina", _*)) => true case _ => false } def main(args: Array[String]): Unit = { val emails = List("liaoad@asiainfo.com", "liaoadliaoad@aisainfo.com", "LIAOLIAO@sina.com", "LIAOAD@QQ.COM") emails.foreach(userTwiceUpper) emails.foreach(x => if (isSinaEmail(x)) println(x)) } } /** * 正则表达式 */ object RegexApp { def main(args: Array[String]): Unit = { import scala.util.matching.Regex //使用 """ 三引号表示一个原始字符串 ,里面的字符串默认不为\转义 (\d即匹配数字 ,\.即匹配.) //RichString提供了 .r 方法 ,将字符串转化成Regex val Decimal = """(-)?(\d+)(\.\d*)?""".r val input = "for -0.1 to 99 by 3" //在字符串中查询数字 生成Seq 打印 for (s <- Decimal findAllIn input) println(s) } }
第二十五章 注解
注解和Java的用法基本相同第二十六章 使用XML
package SecondWithProgrammingInScala /** * 使用XML * * 读写/查询/拆解 * scala可以方便的操作xml ,并在里面嵌入代码 ,或是代码中描述xml */ import scala.xml.{Elem, Node, XML} abstract class CCTherm { val description: String val yearMade: Int val dateObtained: Elem val bookPrice: Int val purchasePrice: Int val condition: Int override def toString: String = description //序列化 def toXml = <cctherm> <description> {description} </description> <yearMade> {yearMade} </yearMade> <dateObtained> {dateObtained} </dateObtained> <bookPrice> {bookPrice} </bookPrice> <purchasePrice> {purchasePrice} </purchasePrice> <condition> {condition} </condition> </cctherm> //反序列化(通过搜索节点) def fromXML(node: Node): CCTherm = new CCTherm { override val condition: Int = { node \ "condition" }.text.trim.toInt override val description: String = { node \ "description" }.text override val bookPrice: Int = { node \ "bookPrice" }.text.trim.toInt override val purchasePrice: Int = { node \ "purchasePrice" }.text.trim.toInt override val yearMade: Int = { node \ "yearMade" }.text.trim.toInt override val dateObtained: Elem = XML.loadString({ node \ "dateObtained" }.toString.trim) } } object XMLApp { //保存到文件 def saveAsFile(fileName: String, node: Node) = { XML.save(fileName + ".xml", node, "UTF-8", true, null) } //从文件读取 def getXMLFromFile(fileName: String): Elem = { XML.loadFile(fileName + ".xml") } //只匹配一层 def proc(node: Node): String = node match { case <dateObtained> {dateObtained} </dateObtained> => "it's obtained in " + { dateObtained \\ "year" }.toString.trim case _ => "unknow" } def main(args: Array[String]): Unit = { //匿名子类 val term = new CCTherm { override val condition: Int = 9 override val description: String = "hot dog #5" override val bookPrice: Int = 2199 override val purchasePrice: Int = 500 override val yearMade: Int = 1952 override val dateObtained: Elem = <base> <year>2006</year> <month>3</month> <day>12</day> 03.12.2006 </base> } //获取xml val termXML = term.toXml println(termXML) //保存xml saveAsFile("XMLUtilTest", termXML) val xmlFromFile = getXMLFromFile("XMLUtilTest") //转换成对象 val obj = term.fromXML(xmlFromFile) println(obj) //将xml转化成text文字 val termText = termXML.text println(termText) //通过签名找到xml子元素(只在根节点下查找) val description = termXML \ "description" println(description) println(termXML \ "day") //深度搜索查找子元素 val dayOfDateObtained = termXML \\ "day" println(dayOfDateObtained) //模式匹配查找 println(proc(termXML)) } }
相关文章推荐
- Scala学习整理[第十九章 泛型和约束系统]<Programming In Scala>
- Scala学习整理[第四-六章 使用Scala运行类/对象]<Programming In Scala>
- Scala学习整理[第三章 入门Ⅱ]<Programming In Scala>
- Scala学习整理[第三十二章 GUI编程]<Programming In Scala>
- Scala学习整理[第三十章 Actor和并发]<Programming In Scala>
- Scala学习整理[第十一-十三章 类型/特质和其应用/包]<Programming In Scala>
- Scala学习整理[第十六章 List应用与排序算法]<Programming In Scala>
- Scala学习整理[第十五章 样本类和模式匹配]<Programming In Scala>
- Scala学习整理[第十章 继承重载应用]<Programming In Scala>
- Scala学习整理[第二十-二十一章 抽象成员和隐式转换]<Programming In Scala>
- Scala学习整理[第十七-十八章 集合和有状态对象]<Programming In Scala>
- Scala学习整理[第二章 入门Ⅰ]<Programming In Scala>
- Scala学习整理[第三十一章 连接符解析]<Programming In Scala>
- Scala学习整理[第十四章 测试]<Programming In Scala>
- Scala学习整理[第七-九章 函数化编程的函数]<Programming In Scala>
- Scala学习整理[第一章 可伸缩的语言]<Programming In Scala>
- Scala学习整理[第二十二-二十三章 List和For循环]<Programming In Scala>
- Scala学习整理[第二十七-二十九章 模块化编程和Java]<Programming In Scala>
- Scala学习整理[总结篇]<Programming In Scala>
- <<unix/linux programming>>学习标记整理