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

Project1

 找回密码
 注册会员
搜索
查看: 6752|回复: 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
星屑
117
在线时间
552 小时
注册时间
2012-8-18
帖子
1429
27
发表于 2014-6-25 12:35:18 | 只看该作者
你们真是可怕,咱都是本着「不按照咱的要求来写都得死」的原则来做的【噗
反正是自己匹配,不如直接做一个DSL算了,何必迎合Ruby的要求呢

点评

= =b 那么加油吧  发表于 2014-6-25 13:14
像我这种写代码写着玩的,学了c++但是基本不用呢……  发表于 2014-6-25 13:11
c++的心态和ruby当然不一样。我用ruby都是优先简洁性的  发表于 2014-6-25 13:10
这是心态问题【好吧我承认最近C++用的有点着魔……  发表于 2014-6-25 13:07
喵的用ruby你还在意效率??  发表于 2014-6-25 13:04
我要填坑!我要背单词!我要学日语!我要每天锻炼!
好吧呵呵= =
回复 支持 反对

使用道具 举报

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?当然这个问题在这里其实不重要,但我希望能给之后留作参考。

点评

明白  发表于 2014-6-21 10:04
$~[:a]  发表于 2014-6-21 10:01
回复 支持 反对

使用道具 举报

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
星屑
6643
在线时间
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

点评

因为匹配括号这个功能我也打算用到……打算写一个伪代码编译器  发表于 2014-6-21 09:28
你说的很对  发表于 2014-6-21 09:27
竟然放到smomo_core里面去了……既然不用slice!了也就不用clone了吧……  发表于 2014-6-21 09:25
萌新瑟瑟发抖
看到我请叫我去干活
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv2.观梦者 (禁止发言)

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

开拓者

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

使用道具 举报

Lv4.逐梦者 (版主)

百合控

梦石
0
星屑
6643
在线时间
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制作大师授权素材推广计划
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-11-16 13:28

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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