【发布时间】:2021-05-28 22:11:18
【问题描述】:
我有一个正则表达式,应该允许我在 Markdown 文档中注释代码片段。基本上它在/*HLS*/ 和/*HLE*/ cmets 之间寻找内容,并将其包装在span 中。它甚至允许一个小的解释,这将成为跨度的标题。
import Foundation
let content = """
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return /*HLS Explanation here!*/viewModel.books.value.count/*HLE*/
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let book = /*HLS*/viewModel.books.value[indexPath.row]/*HLE*/
let cell = tableView.dequeueReusableCell(withIdentifier: "BookCell") as! BookCell
cell.configure(with: book)
return cell
}
}
"""
let regex = try NSRegularExpression(pattern: #"(?s)\/\*HLS\W?(.*?)\*\/(.*?)\/\*HLE\*\/"#)
let range = NSRange(content.startIndex..<content.endIndex, in: content)
let newContent = regex.stringByReplacingMatches(in: content, options: [], range: range, withTemplate: #"<span class="highlight" title="$1">$2</span>"#)
print(newContent)
结果:
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return <span class="highlight" title="Explanation here!">viewModel.books.value.count</span>
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let book = <span class="highlight" title="">viewModel.books.value[indexPath.row]</span>
let cell = tableView.dequeueReusableCell(withIdentifier: "BookCell") as! BookCell
cell.configure(with: book)
return cell
}
}
这正是它应该如何工作的????
但是,当我从第一条评论中删除 Explanation here! 时,正则表达式太贪婪了。
import Foundation
let content = """
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return /*HLS*/viewModel.books.value.count/*HLE*/
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let book = /*HLS*/viewModel.books.value[indexPath.row]/*HLE*/
let cell = tableView.dequeueReusableCell(withIdentifier: "BookCell") as! BookCell
cell.configure(with: book)
return cell
}
}
"""
let regex = try NSRegularExpression(pattern: #"(?s)\/\*HLS\W?(.*?)\*\/(.*?)\/\*HLE\*\/"#)
let range = NSRange(content.startIndex..<content.endIndex, in: content)
let newContent = regex.stringByReplacingMatches(in: content, options: [], range: range, withTemplate: #"<span class="highlight" title="$1">$2</span>"#)
print(newContent)
结果:
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return <span class="highlight" title="/viewModel.books.value.count/*HLE">
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let book = /*HLS*/viewModel.books.value[indexPath.row]</span>
let cell = tableView.dequeueReusableCell(withIdentifier: "BookCell") as! BookCell
cell.configure(with: book)
return cell
}
}
如您所见,viewModel.books.value.count/*HLE 成为标题,然后是 second /*HLE*/ 之前的所有内容。正则表达式应该匹配标题捕获组,直到它遇到的第一个 */,但它不是 - 它一直到第二个。这是为什么?正则表达式应该匹配(.*?)直到它遇到\*\/,对吧?
当我删除 (?s) 标志时,一切都会再次按预期工作,但我希望能够在 /*HLS*/ 和 /*HLE*/ 之间换行。
【问题讨论】: