非贪婪正则表达式无法正常工作(Notepad++ 8.1.1)
Non-greedy regex not working like I would like (Notepad++ 8.1.1)
我在 Windows 10 上使用 Noteapd++ v8.1.1 编辑游戏 Rimworld 的保存文件,以更改地图上项目的位置。
例如,我想移动所有“Building”和“Building_something”(而不是其他 things)从 y=104 到 y=103 在不同项目的列表中(这里,坐标的形式是 (x, 0, y),我稍微简化了代码并添加了行号):
58 <thing Class="Plant">
59 <def>Plant_TreeOak</def>
60 <id>Plant_TreeOak41339</id>
61 <pos>(100, 0, 105)</pos>
62 </thing>
63 <thing Class="Building">
64 <def>Wall</def>
65 <id>Wall28005</id>
66 <pos>(101, 0, 105)</pos>
68 </thing>
69 <thing Class="Building">
70 <def>Wall</def>
71 <id>Wall29667</id>
72 <pos>(103, 0, 105)</pos>
74 </thing>
75 <thing Class="Building">
76 <def>Wall</def>
77 <id>Wall28005</id>
78 <pos>(101, 0, 104)</pos>
80 </thing>
81 <thing Class="Building_Door">
82 <def>Door</def>
83 <id>Door642106</id>
84 <pos>(102, 0, 104)</pos>
86 </thing>
87 <thing Class="Building">
88 <def>Wall</def>
89 <id>Wall29667</id>
90 <pos>(103, 0, 104)</pos>
92 </thing>
93 <thing Class="Plant">
94 <def>Plant_Grass</def>
95 <id>Plant_Grass203219</id>
96 <pos>(104, 0, 104)</pos>
97 </thing>
(这里,在 y=105 上我们有一棵橡树,一堵墙,什么都没有,一堵墙;在 y=104 上我们有一堵墙,一扇门,一堵墙,草)。
我尝试找到 <thing Class="Building(.*?)104\)
(单行)并将其替换为 <thing Class="Building03\)
。
对于此示例,第一个匹配项从第 69 行开始到第 78 行结束,而我希望它从第 75 行开始(接下来的两个匹配项工作正常)。
我尝试了很多东西并寻找了准确的文档但无济于事(我什至找不到 Notepad++ 使用的是什么正则表达式引擎...)。
实际上,我认为我不完全理解“非贪婪”正则表达式的工作原理。
请注意英语不是我的母语,所以技术英语有时对我来说很棘手。
感谢您的帮助,请记住我使用的是 Notepad++,它有时会以不同的方式处理正则表达式(例如,此处替换行中的 \)
生成 )
)。
你可以找到 <thing Class="Building
然后匹配下面的两行,而不是在 )
:
之前的最后一个数字之前抓取所有
<thing Class="Building(?:_[^"]*)?">(?:\R.*){2}\R.*\(.*,\h*\K104(?=\))
替换为103
。见 regex demo.
详情:
<thing Class="Building
- 固定字符串
(?:_[^"]*)?
- _
字符的可选序列,后跟 "
字符 以外的零个或多个字符
">
- 固定字符串
(?:\R.*){2}
- 两行
\R
- 换行序列
.*
- 除换行字符外的 0+ 个字符尽可能多
\(
- 一个 (
字符
.*
- 除换行字符外的 0+ 个字符尽可能多
,\h*
- 一个逗号和 0+ 个水平空格
\K
- 匹配重置运算符丢弃目前匹配的所有文本
104
- 固定值
(?=\))
- 下一个字符必须是 )
.
正则表达式是惰性的。在 给定的 起始位置,这是最小的有效匹配。
改为使用以下内容:
<thing Class="Building(?:(?!<thing).)*?104\)
(?!..)
是 negative lookahead, which is supported per the boost syntax here。我还用给定的数据验证了 NPP ;-)
可以在 https://www.mobzystems.com/online/explain-regular-expression/ 处生成正则表达式的扩展说明。
我在 Windows 10 上使用 Noteapd++ v8.1.1 编辑游戏 Rimworld 的保存文件,以更改地图上项目的位置。
例如,我想移动所有“Building”和“Building_something”(而不是其他 things)从 y=104 到 y=103 在不同项目的列表中(这里,坐标的形式是 (x, 0, y),我稍微简化了代码并添加了行号):
58 <thing Class="Plant">
59 <def>Plant_TreeOak</def>
60 <id>Plant_TreeOak41339</id>
61 <pos>(100, 0, 105)</pos>
62 </thing>
63 <thing Class="Building">
64 <def>Wall</def>
65 <id>Wall28005</id>
66 <pos>(101, 0, 105)</pos>
68 </thing>
69 <thing Class="Building">
70 <def>Wall</def>
71 <id>Wall29667</id>
72 <pos>(103, 0, 105)</pos>
74 </thing>
75 <thing Class="Building">
76 <def>Wall</def>
77 <id>Wall28005</id>
78 <pos>(101, 0, 104)</pos>
80 </thing>
81 <thing Class="Building_Door">
82 <def>Door</def>
83 <id>Door642106</id>
84 <pos>(102, 0, 104)</pos>
86 </thing>
87 <thing Class="Building">
88 <def>Wall</def>
89 <id>Wall29667</id>
90 <pos>(103, 0, 104)</pos>
92 </thing>
93 <thing Class="Plant">
94 <def>Plant_Grass</def>
95 <id>Plant_Grass203219</id>
96 <pos>(104, 0, 104)</pos>
97 </thing>
(这里,在 y=105 上我们有一棵橡树,一堵墙,什么都没有,一堵墙;在 y=104 上我们有一堵墙,一扇门,一堵墙,草)。
我尝试找到 <thing Class="Building(.*?)104\)
(单行)并将其替换为 <thing Class="Building03\)
。
对于此示例,第一个匹配项从第 69 行开始到第 78 行结束,而我希望它从第 75 行开始(接下来的两个匹配项工作正常)。
我尝试了很多东西并寻找了准确的文档但无济于事(我什至找不到 Notepad++ 使用的是什么正则表达式引擎...)。 实际上,我认为我不完全理解“非贪婪”正则表达式的工作原理。
请注意英语不是我的母语,所以技术英语有时对我来说很棘手。
感谢您的帮助,请记住我使用的是 Notepad++,它有时会以不同的方式处理正则表达式(例如,此处替换行中的 \)
生成 )
)。
你可以找到 <thing Class="Building
然后匹配下面的两行,而不是在 )
:
<thing Class="Building(?:_[^"]*)?">(?:\R.*){2}\R.*\(.*,\h*\K104(?=\))
替换为103
。见 regex demo.
详情:
<thing Class="Building
- 固定字符串(?:_[^"]*)?
-_
字符的可选序列,后跟"
字符 以外的零个或多个字符
">
- 固定字符串(?:\R.*){2}
- 两行\R
- 换行序列.*
- 除换行字符外的 0+ 个字符尽可能多\(
- 一个(
字符.*
- 除换行字符外的 0+ 个字符尽可能多,\h*
- 一个逗号和 0+ 个水平空格\K
- 匹配重置运算符丢弃目前匹配的所有文本104
- 固定值(?=\))
- 下一个字符必须是)
.
正则表达式是惰性的。在 给定的 起始位置,这是最小的有效匹配。
改为使用以下内容:
<thing Class="Building(?:(?!<thing).)*?104\)
(?!..)
是 negative lookahead, which is supported per the boost syntax here。我还用给定的数据验证了 NPP ;-)
可以在 https://www.mobzystems.com/online/explain-regular-expression/ 处生成正则表达式的扩展说明。