【问题标题】:Swift: RegEx not returning expected resultsSwift:RegEx 未返回预期结果
【发布时间】:2020-03-15 01:43:36
【问题描述】:

让我以我很擅长做正则表达式作为开头。我正在编写的代码适用于 macOS,而不是 iOS,但我认为在这种情况下并不重要。我正在尝试根据更改范围指标搜索 git diff 返回。这是我正在搜索的内容(变量称为元素):

3b8d5178f4d21e9269547e8f0bae4b7daa7d8206
Author: Steve <xxxxxx@xxxxxxx.com>
Date:   Fri Oct 4 16:55:50 2019 -0400

    Fixed responsiveness of code blocks

diff --git a/examples/video/outstream/pb-ve-outstream-no-server.html b/examples/video/outstream/pb-ve-outstream-no-server.html
index ae813578..e18e31ec 100644
--- a/examples/video/outstream/pb-ve-outstream-no-server.html
+++ b/examples/video/outstream/pb-ve-outstream-no-server.html
@@ -24,7 +24,7 @@ sidebarType: 4

        <div>

-           <div>
+           <div style="width:60vw;">

                <p>Lorem ipsum dolor sit ....</p>
            </div>
@@ -33,7 +33,7 @@ sidebarType: 4
                <p>Prebid Outstream Video Ad</p>
             </div>

-           <div>
+           <div style="width:60vw;">
                <p>Sed ut perspiciatis ...</p>
             </div>
        </div>          
@@ -49,9 +49,9 @@ sidebarType: 4
            Do not forget to exchange the placementId in the code examples with your own placementId!</p>
        </div>

-       <div>
+       <div style="width:60vw;">
            <h4>Place this code in the page header.</h4>
-<pre class="pb-code-hl">
+<pre class="pb-code-hl" style="width:60vw;">
 <!--put javascript code here-->
 &lt;script&gt;
     var pbjs = pbjs || {};
@@ -95,9 +95,9 @@ sidebarType: 4
        </div>

        <!--body code example-->
-       <div>
+       <div style="width:60vw;">
            <h4>Place this code in the page body.</h4>
-<pre class="pb-code-hl">
+<pre class="pb-code-hl" style="width:60vw;">
 <!--put body html and javascript here-->
 &lt;div id='video1'&gt;
    &lt;p&gt;Prebid Outstream Video Ad&lt;/p&gt;

这是我获取更改指标的正则表达式

 do {
     let regex = try NSRegularExpression(pattern: "@@ (.*) @@", options: .caseInsensitive)
     let matches = regex.matches(in: element, options:[], range: NSRange(location: 0, length: element.utf16.count))

     for match in matches {
         let strElement = element as NSString
         arrMatches.append(strElement.substring(with: match.range) as String)

     }
 } catch {
     print ("Error with regex return")
 }

按预期工作,我得到了所有四个实例:

["@@ -24,7 +24,7 @@", "@@ -33,7 +33,7 @@", "@@ -49,9 +49,9 @@", "@@ -95,9 +95,9 @@"]

我现在想捕捉指标之间的变化。但我没有得到任何结果,甚至没有出现错误。这是我正在尝试做的硬编码示例:

do {
   let regex = try NSRegularExpression(pattern: "@@ -24,7 +24,7 @@ (.*) @@ -33,7 +33,7 @@", options: .caseInsensitive)
   let matches = regex.matches(in: element, options:[], range: NSRange(location: 0, length: element.utf16.count))
   print(matches.count)//<--prints 0, expecting 1                  
   for match in matches {
      let strElement = element as NSString
      print(":::" + strElement.substring(with: match.range) as String) //<--Nothing prints
   }
 } catch {
      print ("Error with regex return")//<-but nothing prints here either...
 }

内容有很多制表符和换行符,所以我想知道我是否必须以某种方式在我的正则表达式中考虑这些内容?任何帮助将不胜感激。

我应该得到 4 个结果,第一个结果应该是:

sidebarType: 4

        <div>

-           <div>
+           <div style="width:60vw;">

                <p>Lorem ipsum dolor sit ....</p>
            </div>

第二个结果是变化指示符 2 和 3 之间的内容,第三个结果是 3 和 4 之间的内容,最后是 4 之后的所有内容

【问题讨论】:

  • 如果您打算在@@ -24,7 +24,7 @@@@ -33,7 +33,7 @@ 这两个子字符串之间获取一些文本,请使用"(?s)@@ -24,7 \\+24,7 @@(.*)@@ -33,7 \\+33,7 @@"
  • 查看我添加的编辑。
  • @WiktorStribiżew - 就是这样。谢谢你。让它成为一个答案,我会接受它!
  • 我发布了一个动态正则表达式解决方案。
  • "@@ -24,7 \\+24,7 @@([\\S\\s]*?)@@ -33,7 \\+33,7 @@"

标签: swift regex


【解决方案1】:

你可以使用

(?s)@@(?:\s+[-+]?\d+(?:,\d+)?){2}\s+@@(.*?)(?=@@(?:\s+[-+]?\d+(?:,\d+)?){2}\s+@@|\z)

使用 strElement.substring(with: match.range(at: 1)) as String) 获取第 1 组的值。

regex demo

查看 Swift 代码演示:

let element="3b8d5178f4d21e9269547e8f0bae4b7daa7d8206\nAuthor: Steve <xxxxxx@xxxxxxx.com>\nDate:   Fri Oct 4 16:55:50 2019 -0400\n\n    Fixed responsiveness of code blocks\n\ndiff --git a/examples/video/outstream/pb-ve-outstream-no-server.html b/examples/video/outstream/pb-ve-outstream-no-server.html\nindex ae813578..e18e31ec 100644\n--- a/examples/video/outstream/pb-ve-outstream-no-server.html\n+++ b/examples/video/outstream/pb-ve-outstream-no-server.html\n@@ -24,7 +24,7 @@ sidebarType: 4\n\n        <div>\n\n-           <div>\n+           <div style=\"width:60vw;\">\n\n                <p>Lorem ipsum dolor sit ....</p>\n            </div>\n@@ -33,7 +33,7 @@ sidebarType: 4\n                <p>Prebid Outstream Video Ad</p>\n             </div>\n\n-           <div>\n+           <div style=\"width:60vw;\">\n                <p>Sed ut perspiciatis ...</p>\n             </div>\n        </div>          \n@@ -49,9 +49,9 @@ sidebarType: 4\n            Do not forget to exchange the placementId in the code examples with your own placementId!</p>\n        </div>\n\n-       <div>\n+       <div style=\"width:60vw;\">\n            <h4>Place this code in the page header.</h4>\n-<pre class=\"pb-code-hl\">\n+<pre class=\"pb-code-hl\" style=\"width:60vw;\">\n <!--put javascript code here-->\n &lt;script&gt;\n     var pbjs = pbjs || {};\n@@ -95,9 +95,9 @@ sidebarType: 4\n        </div>\n\n        <!--body code example-->\n-       <div>\n+       <div style=\"width:60vw;\">\n            <h4>Place this code in the page body.</h4>\n-<pre class=\"pb-code-hl\">\n+<pre class=\"pb-code-hl\" style=\"width:60vw;\">\n <!--put body html and javascript here-->\n &lt;div id='video1'&gt;\n    &lt;p&gt;Prebid Outstream Video Ad&lt;/p&gt;"
do {
   let del = "@@(?:\\s+[-+]?\\d+(?:,\\d+)?){2}\\s+@@"
   let regex = try NSRegularExpression(pattern: "(?s)\(del)(.*?)(?=\(del)|\\z)", options: .caseInsensitive)
   let matches = regex.matches(in: element, options:[], range: NSRange(location: 0, length: element.utf16.count))
   print(matches.count)//<--prints 0, expecting 1                  
   for match in matches {
      let strElement = element as NSString
      print(":::" + strElement.substring(with: match.range(at: 1)) as String) //<--Nothing prints
   }
 } catch {
      print ("Error with regex return")//<-but nothing prints here either...
 }

正则表达式是(?s)\(del)(.*?)(?=\(del)|\z) 形式:

  • (?s) - 一个 DOTALL 内联正则表达式修饰符
  • \(del) - 分隔符模式
  • (.*?) - 第 1 组:任何 0+ 个字符,尽可能少
  • (?=\(del)|\z) - 紧随其后,必须是分隔符模式或 (|) 字符串结尾 (\z)。

分隔符模式匹配

  • @@ - 文字字符串
  • (?:\s+[-+]?\d+(?:,\d+)?){2} - 两次出现
    • \s+ - 1+ 个空格
    • [-+]? - 可选的 +-
    • \d+ - 1 位以上
    • (?:,\d+)? - , 和 1+ 位的可选序列
  • \s+ - 1+ 个空格
  • @@ - 文字字符串

【讨论】:

    猜你喜欢
    • 2011-08-09
    • 2010-09-22
    • 2021-05-17
    • 2018-02-19
    • 2018-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多