如何在多行文本块上使用 Xcode 的“查找和替换”
How can I use Xcode's `Find and Replace` on Multiline blocks of text
我有一个包含数百个文本块(部分 C++ 方法调用)的大文件,类似于下面的 Current
块,我希望使用 Xcode's正则表达式替换 将每个更改为类似于下面的 Desired
块,捕获值 0.89f、名称、0.1、0.5 和 2。
请注意,这两个块分别以 new Zapp
和 //d.p.’s to show
开始和结束,因此为了节省手动编辑的工作量,我希望使用正则表达式搜索和替换。
我面临的主要问题是 multi-line
块的性质。如果我们暂时忽略它,我几乎已经在以下 single-line
个块上执行了搜索和替换:
当前:
new Zapp (0.89f // defaultParameterValue , "A name" // name , 0.1 // min , 0.5 // max , 2 // d.p.'s to show
期望:
new Zapp (NormalisableRange<float> (0.1, 0.5) ,NormalisableRange<float> (0.1, 0.5).convertTo0to1(0.89f) , "A name" // name , 2 // d.p.'s to show
查找和替换:
查找:Zapp\s+\((.*)\s+// defaultParameterValue\s+,\s+"(.*)"\s+\/\/\s+name\s+,\s+(.*)\s+\/\/\s+min\s+,\s+(.*)\s+\/\/\s+max\s+,\s+(.*)\s+\/\/\s+d.p.'s
替换:Zapp (NormalisableRange<float> (, ) ,NormalisableRange<float> (, ).convertTo0to1() , "" // name , // d.p.’s
此单行解决方案存在捕获1(1space)、捕获3(4 spaces) 并捕获 5 (3 spaces),否则效果很好:
我尝试使用 [^\s]+
从捕获 1 (0.89f)、捕获 3 (0.1) 和捕获 5 (2) 中消除白色 space 但它没有帮助所以如果有人可以指出原因,我将不胜感激。
我可以使用 \s+
搜索 upper
和 lower
,但我无法将它们放在一起来获得所需的结果。
我在网上看到一些旧帖子暗示 Xcode 可能无法完成此任务。如果这是真的,有人可以建议一种替代方法来完成这项工作吗?
原因是 .*
太贪心了,匹配了 \s+
模式可以匹配的空白,但对于这个贪婪的子模式。
要么使用 lazy/reluctant .*?
:
Zapp\s+\((.*?)\s+// defaultParameterValue\s+,\s+"(.*)"\s+\/\/\s+name\s+,\s+(.*?)\s+\/\/\s+min\s+,\s+(.*?)\s+\/\/\s+max\s+,\s+(.*?)\s+\/\/\s+d.p.'s
或者定义 class 来匹配 floats/integers [-+\w.]+
(有点不精确,但是因为期望值类型已知所以可以)或者双引号文字("([^"\]*(?:\.[^"\]*)*)"
):
Zapp\s+\(([-+\w.]+)\s+// defaultParameterValue\s+,\s+"([^"\]*(?:\.[^"\]*)*)"\s+\/\/\s+name\s+,\s+([-+\w.]+)\s+\/\/\s+min\s+,\s+([-+\w.]+)\s+\/\/\s+max\s+,\s+([-+\d.]+)\s+\/\/\s+d.p.'s
请看Wiktor的回答。他给出了两个解决方案和demo,总体上解决了问题。
不过,感谢 Rich 的回答 Multi line search and replace tool, I discovered AppCode by JetBrains 确实会进行多行搜索和替换:
搜索:
new Zapp\s+\(([^\s]+)\s+// defaultParameterValue\n\s+"(.*)"\s+\/\/\s+name\s+, ([^\s]+)\s+// min\n,\s+([^\s]+)\s+// max\n,\s+([^\s]+)\s+// d.p.'s to show
替换:
new Zapp (NormalisableRange<float> (, )\n\t ,NormalisableRange<float> (, ).convertTo0to1()\n\t\t\t , "" // name\n\t\t\t , // d.p.'s to show
我有一个包含数百个文本块(部分 C++ 方法调用)的大文件,类似于下面的 Current
块,我希望使用 Xcode's正则表达式替换 将每个更改为类似于下面的 Desired
块,捕获值 0.89f、名称、0.1、0.5 和 2。
请注意,这两个块分别以 new Zapp
和 //d.p.’s to show
开始和结束,因此为了节省手动编辑的工作量,我希望使用正则表达式搜索和替换。
我面临的主要问题是 multi-line
块的性质。如果我们暂时忽略它,我几乎已经在以下 single-line
个块上执行了搜索和替换:
当前:
new Zapp (0.89f // defaultParameterValue , "A name" // name , 0.1 // min , 0.5 // max , 2 // d.p.'s to show
期望:
new Zapp (NormalisableRange<float> (0.1, 0.5) ,NormalisableRange<float> (0.1, 0.5).convertTo0to1(0.89f) , "A name" // name , 2 // d.p.'s to show
查找和替换:
查找:Zapp\s+\((.*)\s+// defaultParameterValue\s+,\s+"(.*)"\s+\/\/\s+name\s+,\s+(.*)\s+\/\/\s+min\s+,\s+(.*)\s+\/\/\s+max\s+,\s+(.*)\s+\/\/\s+d.p.'s
替换:Zapp (NormalisableRange<float> (, ) ,NormalisableRange<float> (, ).convertTo0to1() , "" // name , // d.p.’s
此单行解决方案存在捕获1(1space)、捕获3(4 spaces) 并捕获 5 (3 spaces),否则效果很好:
我尝试使用 [^\s]+
从捕获 1 (0.89f)、捕获 3 (0.1) 和捕获 5 (2) 中消除白色 space 但它没有帮助所以如果有人可以指出原因,我将不胜感激。
我可以使用 \s+
搜索 upper
和 lower
,但我无法将它们放在一起来获得所需的结果。
我在网上看到一些旧帖子暗示 Xcode 可能无法完成此任务。如果这是真的,有人可以建议一种替代方法来完成这项工作吗?
原因是 .*
太贪心了,匹配了 \s+
模式可以匹配的空白,但对于这个贪婪的子模式。
要么使用 lazy/reluctant .*?
:
Zapp\s+\((.*?)\s+// defaultParameterValue\s+,\s+"(.*)"\s+\/\/\s+name\s+,\s+(.*?)\s+\/\/\s+min\s+,\s+(.*?)\s+\/\/\s+max\s+,\s+(.*?)\s+\/\/\s+d.p.'s
或者定义 class 来匹配 floats/integers [-+\w.]+
(有点不精确,但是因为期望值类型已知所以可以)或者双引号文字("([^"\]*(?:\.[^"\]*)*)"
):
Zapp\s+\(([-+\w.]+)\s+// defaultParameterValue\s+,\s+"([^"\]*(?:\.[^"\]*)*)"\s+\/\/\s+name\s+,\s+([-+\w.]+)\s+\/\/\s+min\s+,\s+([-+\w.]+)\s+\/\/\s+max\s+,\s+([-+\d.]+)\s+\/\/\s+d.p.'s
请看Wiktor的回答。他给出了两个解决方案和demo,总体上解决了问题。
不过,感谢 Rich 的回答 Multi line search and replace tool, I discovered AppCode by JetBrains 确实会进行多行搜索和替换:
搜索:
new Zapp\s+\(([^\s]+)\s+// defaultParameterValue\n\s+"(.*)"\s+\/\/\s+name\s+, ([^\s]+)\s+// min\n,\s+([^\s]+)\s+// max\n,\s+([^\s]+)\s+// d.p.'s to show
替换:
new Zapp (NormalisableRange<float> (, )\n\t ,NormalisableRange<float> (, ).convertTo0to1()\n\t\t\t , "" // name\n\t\t\t , // d.p.'s to show