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

Project1

 找回密码
 注册会员
搜索
查看: 7039|回复: 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的解答,现在的代码是
代码

评分

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

查看全部评分

Lv1.梦旅人

梦石
0
星屑
122
在线时间
552 小时
注册时间
2012-8-18
帖子
1429
27
发表于 2014-6-25 12:35:18 | 只看该作者
你们真是可怕,咱都是本着「不按照咱的要求来写都得死」的原则来做的【噗
反正是自己匹配,不如直接做一个DSL算了,何必迎合Ruby的要求呢
我要填坑!我要背单词!我要学日语!我要每天锻炼!
好吧呵呵= =
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

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

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

开拓者贵宾

26
 楼主| 发表于 2014-6-21 06:27:50 | 只看该作者
本帖最后由 taroxd 于 2014-6-21 06:56 编辑
晴兰 发表于 2014-6-20 22:02
Ruby的正则可能没有其他语言的正则平衡组,但有一个叫做递归匹配的语法,大概的含义就是
mygroup应该匹配{m ...


那么我再问一个问题,如何在gsub中引用a?当然这个问题在这里其实不重要,但我希望能给之后留作参考。
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

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

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

开拓者贵宾

25
 楼主| 发表于 2014-6-21 05:55:30 | 只看该作者
本帖最后由 taroxd 于 2014-6-21 07:36 编辑
晴兰 发表于 2014-6-20 22:02
Ruby的正则可能没有其他语言的正则平衡组,但有一个叫做递归匹配的语法,大概的含义就是
mygroup应该匹配{m ...


在Ruby文档里找到了 Subexpression Calls,这个功能似乎就是专为这个时候设计的

十分感谢,问题解决了。如果真要追究 #{'}'} 的话就得语法分析了吧
回复 支持 反对

使用道具 举报

Lv4.逐梦者 (版主)

百合控

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

开拓者

24
发表于 2014-6-20 22:05:33 | 只看该作者
本帖最后由 余烬之中 于 2014-6-20 22:22 编辑
taroxd 发表于 2014-6-20 21:14
很感谢你的方法……让我参考一下……不过我要的还有替换功能啊233
而且用你的方法,我无法判断那些属于“ ...


FUCK 我居然没有想到
->{puts '}'}
这个用我的方法会匹配错误

不对 我被绕进去了
我这个方法的目的只是分组匹配
在这个范围内使用毫无问题

顺便 楼上正则式的链接 http://rubular.com/r/KB9DX2hV4U

==========================

改了一下result的数据结构 现在是二维数组了 第一个表示字符 第二个表示深度 以最外层没有括号的为0深度
RUBY 代码复制
  1. def mBrackets str, brackets = {'(' => ')', '[' => ']', '{' => '}', '<' => '>'}
  2.   matched = []
  3.   result = [["", 0]]
  4.   valid = [0]
  5.   str.clone.each_char do |c|
  6.     valid.each{|v| result[v][0].concat(c)}
  7.     if brackets.keys.include?(c)
  8.       matched.push(c)
  9.       valid.push(result.size)
  10.       result.push(["", valid.size - 1])
  11.     elsif brackets.values.include?(c)
  12.       if brackets[matched[-1]] == c
  13.         result[valid[-1]][0].chop!
  14.         valid.pop
  15.         matched.pop
  16.       else
  17.         raise ArgumentError, "False Matching!"
  18.       end
  19.     end
  20.   end
  21.   result
  22. end
萌新瑟瑟发抖
看到我请叫我去干活
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv2.观梦者 (禁止发言)

梦石
0
星屑
653
在线时间
3774 小时
注册时间
2011-2-26
帖子
1839

开拓者

23
发表于 2014-6-20 22:02:15 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复 支持 反对

使用道具 举报

Lv4.逐梦者 (版主)

百合控

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

开拓者

22
发表于 2014-6-20 21:44:09 | 只看该作者
本帖最后由 余烬之中 于 2014-6-20 21:59 编辑
taroxd 发表于 2014-6-20 21:14
很感谢你的方法……让我参考一下……不过我要的还有替换功能啊233
而且用你的方法,我无法判断那些属于“ ...


"#{'}'}" #=> "}"
'#{\'}\'}' #=> "\#{'}'}" # 期望-> "}"
'#{"Foo" + \'} + "Bar"\'}' #=> "\#{\"Foo\" + '}' + \"Bar\"}" # 期望-> "Foo}Bar"

是这样吗

---------
一开始忘了each_char 用了each_byte 结果不能处理双字节 最后还是用了clone+slice!  然后突然想到了这东西 一下子ruby了

评分

参与人数 1梦石 +2 收起 理由
恐惧剑刃 + 2

查看全部评分

萌新瑟瑟发抖
看到我请叫我去干活
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

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

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

开拓者贵宾

21
 楼主| 发表于 2014-6-20 21:14:24 | 只看该作者
本帖最后由 taroxd 于 2014-6-20 21:33 编辑
余烬之中 发表于 2014-6-20 21:05
就这样 完成了一个方法
方法不能直接使用 满足你的适用范围的话 必须先处理字符串 将不需要处理的括号转义  ...


很感谢你的方法……让我参考一下……不过我要的还有替换功能啊233
而且用你的方法,我无法判断那些属于“最外层”。因为你的输出结果是从左至右,而不是由外到内。当然这一点是可以通过 valid.size == 1 来进行判断的
如果我不是需要 i 来表示位置的话,大概也不会比你的方法繁琐吧。
总之虽然我用不到,还是很感谢

另外继续为难一下: '#{\'}\'}'(显示为#{'}'}),替换为}
(这是ruby的双引号中可以做到的)

反正我是没成功
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

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

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

开拓者贵宾

20
 楼主| 发表于 2014-6-20 21:10:50 | 只看该作者
moy 发表于 2014-6-20 21:07
……我也没弄明白

https://rpg.blue/thread-365976-1-1.html
最上端的脚本提供了 V, S, A 之类“常量”的定义

实在不行还能读取全局变量的嘛~
回复 支持 反对

使用道具 举报

Lv2.观梦者

无节操

梦石
0
星屑
607
在线时间
795 小时
注册时间
2009-2-6
帖子
3939

开拓者贵宾

19
发表于 2014-6-20 21:07:37 | 只看该作者
taroxd 发表于 2014-6-20 21:03
不懂你在说什么

我只知道有了这货我可以做许多死,比如道具的描述随队伍而变化,比如在显示文字里面直插 ...
  1. a = "#{xyz}"
  2. #=> no methods or variables name“xyz”
复制代码
……我也没弄明白

点评

moy
……我看你们写的我迷惑了半天(  发表于 2014-6-20 21:24
其实我想说……"#{xyz}"不写在脚本里 脚本里要处理一下 不能直接转义了 例如"#插一下{xyz}" 要处理这个字面值  发表于 2014-6-20 21:22
Brandnew day, Brandnew Life
                              实在  中
暂为素材区版主,版其  琢磨
应援一下~
RPG制作大师授权素材推广计划
回复 支持 反对

使用道具 举报

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

本版积分规则

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

站长信箱:fux2@moe9th.com|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2025-7-11 05:03

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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