All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.reactific.helpers.Patterns.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2015-2017 Reactific Software LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.reactific.helpers

import scala.util.matching.Regex

/** One line sentence description here.
 * Further description here.
 */
object Patterns {

  /** Join a sequence of patterns together */
  def join(r: Regex*): Regex = {
    val initialBufferSize = 1024
    val result: StringBuffer = new StringBuffer(initialBufferSize)
    r.foldLeft(result) {
        case (result: StringBuffer, regex: Regex) ⇒
          result.append(regex.unanchored.pattern.pattern); result
      }
      .toString
      .r
  }

  private def serialize(r: Seq[Regex]): String = r.foldLeft("") {
    case ((x, y)) ⇒ x + y.pattern.pattern
  }

  /** Make a pattern into various repeating forms of itself  */
  def anchored(r: Regex*): Regex = ("^" + serialize(r) + "$").r
  def group(r: Regex*): Regex = ("(?:" + serialize(r) + ")").r

  def capture(r: Regex, name: String = ""): Regex = {
    if (name.isEmpty) {
      s"(${r.pattern.pattern})".r
    } else {
      s"(?<$name>${r.pattern.pattern})".r
    }
  }
  def optional(r: Regex): Regex = ("(?:" + r.pattern.pattern + ")?").r
  def atLeastOne(r: Regex): Regex = ("(?:" + r.pattern.pattern + ")+").r
  def oneOrMore(r: Regex): Regex = atLeastOne(r)
  def zeroOrMore(r: Regex): Regex = ("(?:" + r.pattern.pattern + ")*").r

  def between(min: Int, max: Int, r: Regex): Regex =
    ("(?:" + r.pattern.pattern + s"){$min,$max}").r

  def alternate(r1: Regex, r2: Regex): Regex =
    ("(?:" + r1.pattern.pattern + ")|(?:" + r2.pattern.pattern + ")").r

  // From RFC 2822. The pattern names below match the grammar production
  // names and definitions from the RFC
  lazy val atext: Regex = "[-A-Za-z0-9!#$%&'*+/=?^_`|~]".r
  lazy val atom: Regex = atLeastOne(atext)
  lazy val dot_atom: Regex = join(atom, zeroOrMore(join("[.]".r, atom)))
  lazy val no_ws_ctl: Regex =
    "[\\u0001-\\u0008\\u000B-\\u000C\\u000E-\\u001F\\u007F]".r
  lazy val qtext: Regex =
    alternate(no_ws_ctl, "[!\\u0023-\\u005B\\u005D-\\u007E]".r)
  lazy val quoted_string: Regex = join("\"".r, zeroOrMore(qtext), "\"".r)
  lazy val local_part: Regex = alternate(dot_atom, quoted_string)
  lazy val quoted_pair: Regex = "\\\\.".r
  lazy val dtext: Regex = join(no_ws_ctl, "[!-Z^-~]".r)
  lazy val dcontent: Regex = alternate(dtext, quoted_pair)
  lazy val domain_literal: Regex = join("\\[]".r, zeroOrMore(dcontent), "]".r)
  lazy val domain_part: Regex = alternate(dot_atom, domain_literal)
  lazy val addr_spec: Regex = join(group(local_part), "@".r, group(domain_part))

  lazy val EmailAddress: Regex = addr_spec
  lazy val Identifier: Regex = "[-\\w_+=|!.^@#%*?]+".r
  lazy val Markdown: Regex =
    "[-\\s\\w~`!@#$%^&*()_+={}\\[]|\\\\:;\"'<>,.?/ ]*".r
  lazy val Password: Regex = between(6, 64, Markdown)
  lazy val LegalName: Regex =
    join(Identifier, zeroOrMore(join(" ".r, Identifier)))

  // TODO: convert these patterns to use the constructors so we
  // can comprehend them!
  lazy val DomainName: Regex =
    ("(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*[a-zA-Z0-9])\\.){0,126}" +
      "(?:[A-Za-z0-9][-A-Za-z0-9]*[A-Za-z0-9])").r
  lazy val TcpPort: Regex =
    "\\d{1,4}|[0-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5]".r
  lazy val IPv4Address: Regex =
    ("(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" +
      "(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])").r
  lazy val UniformResourceLocator: Regex =
    ("^(https?|ftp|file)://" +
      "[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]$").r

  lazy val URLPathable: Regex = "[-A-Za-z0-9_.~]{1,64}".r

  lazy val Title: Regex = between(4, 70, "[-\\s\\w\\d+:%!_{}|;<>,.?]".r)

  lazy val NotAllowedInUrl: Regex = "[^-\\w\\d._+|]".r
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy