使用Swift中的正则表达式来定位双引号

时间:2017-07-07 19:29:23

标签: regex swift

我一直在尝试使用Swift中的正则表达式在字符串中提取一段文本。我要提取的文本在双引号内,所以我试图将这些双引号作为目标并获取内部文本。

这是我正在使用的RegExp:(?<=")(?:\\.|[^"\\])*(?=")

它适用于任何类型的文本,它可以更简单,因为我正在寻找可能在这些双引号内的任何内容。

当我尝试将此RegExp与Swift一起使用时,我必须在其中使用双引号,但出于某种原因,RegExp不适用于转义双引号,例如(?<=\")(?:\\.|[^\"\\])*(?=\")

即使我尝试了一些简单的\",RegExp也不匹配字符串中的任何双引号。

代码示例

func extractText(sentence: String?) -> String {
    let pattern = "(?<=\")(?:\\.|[^\"\\])*(?=\")"
    let source = sentence!

    if let range = source.range(of: pattern, options: .regularExpression) {
        return "Text: \(source[range])"
    }

    return ""
}

extractText("Hello \"this is\" a test") -> "this is"

要记住:

  • 所有这些RegExp必须在双引号内,以创建将用作模式的字符串文字。
  • 我正在使用字符串的range方法和.regularExpression选项来匹配内容。
  • 我正在使用Swift 4和Xcode 9 Playground

如何在Swift中使用双引号来成功匹配字符串?

解决方案

感谢@Atlas_Gondal和@vadian我发现问题“部分”不是RegExp,而是我得到的字符串,它使用不同类型的双引号“ ... ”所以我必须改变我的模式为了使用它,可以使用"(?<=“).*(?=”)"之类的东西。

结果代码如下所示:

func extractText(sentence: String?) -> String {
    let pattern = "(?<=“).*(?=”)"
    let source = sentence!

    if let range = source.range(of: pattern, options: .regularExpression) {
        return "\(source[range])"
    }

    return ""
}

2 个答案:

答案 0 :(得分:1)

带有range(of选项的

regularExpression无法执行此操作,因为它无法捕获组。

您需要真实 NSRegularExpression

func extractText(sentence: String) -> String {
    let pattern = "\"([^\"]+)\""
    let regex = try! NSRegularExpression(pattern: pattern)


    if let match = regex.firstMatch(in: sentence, range: NSRange(location: 0, length: sentence.utf16.count)) {
        return (sentence as NSString).substring(with: match.rangeAt(1))
    }

    return ""
}

extractText(sentence:"Hello \"this is\" a test")

模式更简单:搜索双引号,后跟一个或多个非双引号字符,后跟结束双引号。捕获双引号之间的字符。

请注意,文字字符串中的转义双引号只是虚拟转义。

PS:如果没有Swift 3中的参数标签也不能编译代码。

答案 1 :(得分:0)

试试这段代码:

.header {
  background-color: #FFB6C1;
  color: black;
  overflow: hidden;
  position: relative;
}

.inner-wrapper {
  width: 80%;
  margin: 0 auto;
  margin-top: 30px;
  margin-bottom: 20px;
}

.header h2 {
  float: left;
  font-family: 'Pacifico', sans-serif;
  font-size: 30px;
}

.header h3 {
  padding-top: 5px;
  font-family: 'Petit Formal Script';
  clear: both;
  font-weight: 700;
}

.header span {
  font-weight: bolder;
}

.header ul {
  float: right;
  margin-right: 10%
}

.header ul li {
  list-style: none;
  display: inline-block;
  font-family: 'Podkova', sans-serif;
  margin-right: 20px;
  font-weight: bold;
}
/* Navigation Menu click for mobile */

.mobile-menu {
  padding: 0;
  margin: 0;
  display: none;
}
/* Smartphones (portrait) ----------- */

@media only screen and (max-width: 414px) {
  /* Styles */
  /* Display flex to change the ordering of HTML elemtns*/
  .inner-wrapper {
    display: flex;
    flex-direction: column;
    margin-bottom: 0px;
  }
  .header-title {
    order: 1;
  }
  .header-description {
    order: 2;
  }
  .dropdown {
    order: 3;
  }
  .header-li {
    display: none;
    position: absolute;
    width: 100%;
  }
  .header ul {
    float: none;
    margin-right: 0%;
  }
  .mobile-menu {
    padding: 0;
    margin: 0;
    display: initial;
    cursor: pointer;
  }
  .header ul li {
    width: 100%;
    background-color: green;
    padding-top: 20px;
  }
  .header {
    position: relative;
    width: 100%;
  }
}

使用这样的扩展程序:

<!-- Header and Navigation -->
<div class="header">
  <div class="inner-wrapper">
    <h2 class="header-title">text</h2>
    <div class="dropdown">
      <div class="mobile-menu">
        <p align="right">Menu</p>
      </div>
      <ul class="header-li">
        <li>About me</li>
        <li>Progress</li>
        <li>Food</li>
        <li>Contact</li>
      </ul>
    </div>
    <h3 class="header-description">text</span></h3>
  </div>
</div>

示例屏幕截图 enter image description here