^ a | A $和^(a | A)$之间有什么区别?

时间:2017-04-09 08:11:10

标签: regex

^a|A$ ^(a|A)$ 有什么区别?

感谢

2 个答案:

答案 0 :(得分:4)

import java.util.concurrent.atomic.AtomicInteger import akka.actor.ActorSystem import akka.stream.ActorMaterializer import akka.stream.scaladsl.{Keep, Sink, Source} import org.scalatest.FlatSpec import scala.concurrent.duration.Duration import scala.concurrent.{Await, Future} object TestProtocol { case class Token(value: String) extends AnyVal type Result = Future[Boolean] } import TestProtocol._ trait WithRefreshes { def sinkWithRefresh(): Sink[String, Result] def sourceWithRefresh(): Source[String, Result] } // code to fix / implement starts class WithRefreshesImpl(api: Api) extends WithRefreshes { var token: Token = Await.result(api.refreshToken(), Duration.Inf) // TODO: we want to cache tokens to avoid refreshing them again and again override def sinkWithRefresh(): Sink[String, Result] = { api.sink(token) // TODO: we want to refresh tokens when needed } override def sourceWithRefresh(): Source[String, Result] = { api.source(token) // TODO: we want to refresh tokens when needed } } // code to fix / implement ends trait Api { def sink(token: Token): Sink[String, Result] def source(token: Token): Source[String, Result] def refreshToken(): Future[Token] } class MockApi(data: String) extends Api { private val expiredToken = Token("expired") private val successfulToken = Token("ok") private val failedToken = Token("failed") private val refreshTokenCount = new AtomicInteger() override def sink(token: Token): Sink[String, Result] = { Sink.ignore.mapMaterializedValue(_ => Future.successful(token == successfulToken)) } override def source(token: Token): Source[String, Result] = { if (token == successfulToken) { Source.single(data).mapMaterializedValue(_ => Future.successful(true)) } else { Source.empty[String].mapMaterializedValue(_ => Future.successful(false)) } } /** Returning expired token on first invocation, then a successful token on the second one, then failed tokens for subsequent invocations*/ override def refreshToken(): Future[Token] = { val result = refreshTokenCount.getAndIncrement() match { case 0 => expiredToken case 1 => successfulToken case _ => failedToken } Future.successful(result) } } import org.scalatest.concurrent.ScalaFutures._ import org.scalatest.Matchers._ class TestSpec extends FlatSpec { implicit val system = ActorSystem() implicit val materializer = ActorMaterializer() val data = "data" it should "work for uploads" in { val mockApi = new MockApi(data) val withRefreshes = new WithRefreshesImpl(mockApi) val sink = withRefreshes.sinkWithRefresh() val result = Source.single("test").runWith(sink) whenReady(result) { _ shouldEqual true } } it should "work for downloads" in { val mockApi = new MockApi(data) val withRefreshes = new WithRefreshesImpl(mockApi) val source = withRefreshes.sourceWithRefresh() val (result, dataF) = source.toMat(Sink.seq)(Keep.both).run whenReady(result) { _ shouldEqual true } whenReady(dataF) { _ shouldEqual data } } } 匹配以^a|A$开头或以a结尾的字符串。这将允许Aabcd作为有效字符串。

dcbA匹配^(a|A)$a字符串。此值也会捕获到一个组中,以后可以访问该组。

创建一个模式时,第一个模式通常是一个错误,该模式应检查整个字符串是否有一些变化。在这些情况下,A^应始终位于更改的分组结构之外。可以使用非捕获组$来避免捕获值。有些语言也有内置的全匹配功能,应该优先考虑那些情况(比如pythons re.fullmatch)

答案 1 :(得分:1)

^a|A$ 
  • 第一选择^ a 字面匹配字符(区分大小写) ^断言字符串开头的位置 a字面匹配(区分大小写)
  • 第二选择A $ A字面匹配字符A(区分大小写) $断言字符串末尾的位置,或者在字符串末尾的行终止符之前(如果有的话)

    ^(A | A)$

  • ^断言字符串开头的位置    第一捕获组(a | A)    第一选择a    a字面匹配(区分大小写)

  • 第二种选择A.    A字面匹配字符A(区分大小写)    $断言字符串末尾的位置,或者在字符串末尾的行终止符之前(如果有的话)