设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 6762|回复: 26
打印 上一主题 下一主题

[讨论] 如何匹配字符串中的成对括号?

[复制链接]

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

跳转到指定楼层
1
发表于 2014-6-20 18:06:31 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 taroxd 于 2014-7-21 20:32 编辑

技术讨论区向来是脚本大触的后花园,于是我来打破这一现状,来问脚本新手问题啦~

我想要在事件-显示文字等地方实现 #{} 这种类似 ruby 内嵌表达式的功能。
而喵呜喵的版本中,至少有两个美中不足之处。
1. 当你真的需要输入#{}时无法输入
2. 表达式不能内嵌花括号{}

问题 1 很容易解决,和ruby的双引号字符串一样,可以通过 \#{} 来实现
而问题 2 就是我想请教的。如何较为简洁地实现括号配对,进行匹配的功能?

我正则表达式学艺不精,因此只尝试了最原始的循环方式。
以下是我尝试的,不美观而且难以理解的代码(发布于此)。
其中 old 是原方法的返回值,也就是要进行处理的字符串。
Taroxd::Script.process 方法是对代码做一些处理,定义在上面的链接中,与这个问题无关。
代码


用ruby写出这种代码毕竟是非常难受的事情,而且匹配成对括号的功能我以后可能还会再次用到。因此我来请教,有什么更好的解决方式没有?
而且,我的方法还有个问题,比如说 #{'}'} 就会发生错误,而正确的解释为 "}"

感谢23L的解答,现在的代码是
代码

点评

#{$game_party.members.inject(0) {|sum, actor| sum + actor.hp }}  发表于 2014-6-20 18:48
#{$game_party.members.inject(0) {|sum, actor| sum + actor }} 这是个正常向的  发表于 2014-6-20 18:48
#{'#{}'} 这个想过,太烦了=。= 而且我想问的不是这个……  发表于 2014-6-20 18:46
#{}123#{44+1}67#{}89\#{}\\#{{sym: true}}  发表于 2014-6-20 18:45
#{'#{123456}'}  发表于 2014-6-20 18:43

评分

参与人数 1星屑 +300 收起 理由
恐惧剑刃 + 300 精品文章

查看全部评分

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
42404
在线时间
7602 小时
注册时间
2009-7-6
帖子
13506

开拓者贵宾

2
发表于 2014-6-20 18:50:01 | 只看该作者
默认贪婪匹配应该没什么问题吧,我暂时没想到什么问题。
RUBY 代码复制
  1. \([^\(\)]*\)

大概能想到的只有这样,匹配一层括号中的内容,循环匹配之后清除掉就好了。

点评

因此会直接匹配最内层括号(456)  发表于 2014-6-20 19:37
[^\(\)]不能匹配俩括号?好吧才反应过来。可是"(123(456)789)(0)"不会被"3(4"卡住吗?  发表于 2014-6-20 19:35
\([^\(\)]*\) 匹配最内层的括号  发表于 2014-6-20 19:26
可以匹配上 但是会错误吧?比如"(123456)(7890)"默认贪婪会匹配"123456)(7890" 而预期的不是"123456"和"7890"吗  发表于 2014-6-20 19:25
余烬的这段到底是字符串还是啥,直接返回结果有问题吗。  发表于 2014-6-20 19:22
RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

3
 楼主| 发表于 2014-6-20 19:01:19 | 只看该作者
fux2 发表于 2014-6-20 18:50
默认贪婪匹配应该没什么问题吧,我暂时没想到什么问题。
\([^\(\)]*\)[/pre]
大概能想到的只有这样 ...

清除掉之后怎么装回去?

因为我需要最外层括号内的完整内容
如:(1)) 匹配1
      ((1) 匹配失败
      ((1)) 匹配(1)
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
42404
在线时间
7602 小时
注册时间
2009-7-6
帖子
13506

开拓者贵宾

4
发表于 2014-6-20 19:03:05 | 只看该作者
taroxd 发表于 2014-6-20 19:01
清除掉之后怎么装回去?

因为我需要最外层括号内的完整内容

你把字符串克隆一份再进行破坏性操作嘛。
RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

5
 楼主| 发表于 2014-6-20 19:04:53 | 只看该作者
本帖最后由 taroxd 于 2014-6-20 19:07 编辑
fux2 发表于 2014-6-20 19:03
你把字符串克隆一份再进行破坏性操作嘛。


求演示

测试字符串 #{}123#{44+1}67#{}89\#{}\\#{{sym: true}}
结果 123456789#{}\{:sym=>true}

克隆完之后,匹配原字符串只能得到括号起始的位置。而这个位置其实不需要层层匹配也可以直接获得的吧?
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
42404
在线时间
7602 小时
注册时间
2009-7-6
帖子
13506

开拓者贵宾

6
发表于 2014-6-20 19:11:34 | 只看该作者
taroxd 发表于 2014-6-20 19:04
求演示

测试字符串 #{}123#{44+1}67#{}89\#{}\\#{{sym: true}}

我以为你说的是正则匹配括号,看来跑题了.
无论怎么样也不可能得到这样的结果吧,你的表达式本来就是错误的。

点评

sym:true能得到:sym=>true这样的结果本身就很奇怪啦。  发表于 2014-6-20 19:19
表达式无误。1L代码可以得到这样的结果(当然是把大括号内的东西eval了)  发表于 2014-6-20 19:16
RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

7
 楼主| 发表于 2014-6-20 19:22:07 | 只看该作者
fux2 发表于 2014-6-20 19:11
我以为你说的是正则匹配括号,看来跑题了.
无论怎么样也不可能得到这样的结果吧,你的表达式本来就是错误 ...

{sym: true} 是 Ruby1.9 之后的一个哈希的语法啦
等价于 {:sym => true},这玩意儿 to_s 当然就是 {:sym=>true}

点评

= =我一般只在给别人讲ruby meta-programming的时候提到ruby……可能是因为我用ruby越来越少了233  发表于 2014-6-25 12:55
仅在核心方法,表示一个东西的名字的时候,这两个才会通用啊  发表于 2014-6-25 12:52
怎么可能可以一起使用,你拿string索引hash中的symbol试试  发表于 2014-6-25 12:51
Symbol和String经常可以一起使用了= =简直丧病,说好的强类型呢  发表于 2014-6-25 12:28
再开irb试了一下,是符号没错……天呐这还是我平时最常用的哈希语法!我都不知道为什么几个月来从来没有出过问题  发表于 2014-6-20 19:31
回复 支持 反对

使用道具 举报

Lv4.逐梦者 (版主)

百合控

梦石
0
星屑
6643
在线时间
1275 小时
注册时间
2013-8-21
帖子
3657

开拓者

8
发表于 2014-6-20 19:22:30 | 只看该作者
打算尝试一下【匹配成对括号】这个方法本身
参数:待匹配字符串
返回值:括号内内容的数组?
萌新瑟瑟发抖
看到我请叫我去干活
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

9
 楼主| 发表于 2014-6-20 19:24:37 | 只看该作者
余烬之中 发表于 2014-6-20 19:22
打算尝试一下【匹配成对括号】这个方法本身
参数:待匹配字符串
返回值:括号内内容的数组? ...

由于我是要实现 #{} 这种类似 ruby 内嵌表达式的功能

因此只需要最大的一个花括号里的内容就行了

#{{} ← 没有匹配
#{}} ← 匹配 #{}
#{{}} ← 匹配 #{{}}

我的原始方法实现至少是可以完成这个功能的……
回复 支持 反对

使用道具 举报

Lv4.逐梦者 (版主)

百合控

梦石
0
星屑
6643
在线时间
1275 小时
注册时间
2013-8-21
帖子
3657

开拓者

10
发表于 2014-6-20 19:37:25 | 只看该作者
本帖最后由 余烬之中 于 2014-6-20 19:38 编辑
taroxd 发表于 2014-6-20 19:24
由于我是要实现 #{} 这种类似 ruby 内嵌表达式的功能

因此只需要最大的一个花括号里的内容就行了


只需要最外层?直接贪婪不久好了?

或者是这样:"文字#{待处理内容}文字#{另一些待处理内容}"

另外你的例子我看不懂 是不是这样:

#{{} ← 没有匹配
#{}} ← 匹配 }
#{{}} ← 匹配 {}
萌新瑟瑟发抖
看到我请叫我去干活
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-23 21:06

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表