刚才正无聊,在JavaEye的问答区Ruby分类里看到了这样一问:
http://www.iteye.com/problems/3
tianshi0253 写道
从键盘输入一组数据,如:“测试,JAVAEYE!”,输出的结果为:“!JAVAEYE,试测”。
并且把它们存储到一个TXT文本中。
这简单的功能要求也挺有趣的,就尝试了一下。
基本思路是先使用String#split,然后用Array#reverse,最后用File.open和puts做输出。所以关键的地方就是要传给String#split的正则表达式参数了。
先忽略中文和全角字符,假设我们处理的都是ASCII字符。然后,那题目看来是要把某些字符看作分隔符来讲字符串分割开来,但同时要求分隔符也被保留。没有明确要求空白字符如何处理,这里假设空白字符在目标字符串中被忽略。
我们知道,给String#split的参数里的正则表达式所能匹配的子串会被“吃掉”,所以为了匹配分隔符而又不让它们被“吃掉”,我们就需要“零长度匹配”,或者叫“环视”(lookaround)。
同时使用正向和逆向环视(lookahead和lookbehind),我们就能够完成对指定的分隔符的匹配和分隔,同时在目标字符串中保留它们。所以最终的程序会类似这样:
split = ",.!?" # 可以将别的字符定义为分隔符
file_path = "D:/result.txt" # 可以从别的地方获取输出的文件的路径
File.open(file_path, "w") do |file|
file.puts gets.chomp.split(/\s*(?:(?<=[#{split}])|(?=[#{split}]))\s*/).reverse.join("")
end
这样,当我们执行这个程序,并且在命令行输入下面的字符串时:
Hello, JavaEye!
在D:\result.txt里我们就会得到:
!JavaEye,Hello
差不多了吧?注意到空格被去掉了(基于上面的假设)
来仔细看看那个正则表达式(先将split带入进去):
/\s*(?:(?<=[#{split}])|(?=[#{split}]))\s*/
一头一尾都是匹配任意个数的空白字符:\s*
中间是一个非捕获型分组(? ... )
这个分组内有两个选择,前一个是逆向环视,用于匹配左边有分隔符的情况:(?<=[,.!?])
后一个是正向环视,用于匹配右边有分隔符的情况:(?=[,.!?])
这样就大致的解决了那个问题,只是……
(又有“只是”了)嗯,用Ruby 1.8.x来执行上面的代码是行不通的。因为Ruby采用的正则表达式引擎是自己实现的,而不是PCRE或者Perl自身用的那个,不支持逆向环视。
幸好,在Ruby 1.9.0里,正则表达式的引擎换成了Oniguruma(鬼車),总算支持了逆向环视。前面的代码的运行就是在Ruby 1.9.0-0上测试的。
但是……
还有一个重要的问题暂时被忽略了:中文和全角符号的支持。
如果是以UNICODE为内部编码表示的语言,那这根本不是问题;所以像是C#啊Java之类的都不会碰到什么问题。但是Ruby直到1.8.6为止对UTF-8/UTF-16/Shift-JIS以外的编码的支持都挺糟糕的。Windows下的控制台一般是设置到操作系统的默认locale,在简体中文Windows上就是GBK。这样输入到Ruby解释器里的中文字符串就可能有问题
假如把上面代码中的分隔符设置为",!"(注意到是全角字符),然后保存为UTF-8的源码文件,那么运行的时候会出错:
split.rb:4:in `split': incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string) (ArgumentError)
from split.rb:4:in `block in <main>'
from split.rb:3:in `open'
from split.rb:3:in `<main>'
假如还是保存为ANSI(简体中文Windows上也就是GBK),那么运行的结果就不太对:
。JavaEye测试
我也不知道有什么好办法来解决这个问题……GUI程序的话说不定还有点办法,控制台程序真是一点办法都没有(总不能要求用户为了这么个小程序去调整控制台编码吧 = =)
平时自己写的小程序多半都只用英文,就避开了这个问题。但是要是写给别人用,而又非要用中文的话,那我还真的不知道怎么办好了。Sigh。
分享到:
相关推荐
在本案例中,我们可能在"数组逆序重存放(信息学奥赛一本通-T1105).pdf"文件中找到详细的解题思路、示例和可能的解决方案。 数组是计算机科学中最基本的数据结构之一,它是一系列相同类型元素的集合,可以通过索...
字符串逆序字符串逆序字符串逆序字符串逆序字符串逆序字符串逆序
字符串逆序+c语言字符串逆序输出+c语言字符串逆序逐行解释字符串逆序+c语言字符串逆序输出+c语言字符串逆序逐行解释字符串逆序+c语言字符串逆序输出+c语言字符串逆序逐行解释字符串逆序+c语言字符串逆序输出+c语言...
这段代码首先定义了一个`reverse`函数,接受一个整型数组和它的大小作为参数,然后通过两个指针`i`和`j`进行逆序操作。在`main`函数中,我们创建了一个数组`nums`并打印原数组,调用`reverse`函数逆序排列,最后再次...
c 语言字符串逆序 c 语言字符串逆序c 语言字符串逆序 c 语言字符串逆序c 语言字符串逆序 c 语言字符串逆序c 语言字符串逆序 c 语言字符串逆序c 语言字符串逆序 c 语言字符串逆序c 语言字符串逆序 c 语言字符串逆序c ...
此程序是课程学习中的数组逆序,希望对大家有帮助
C语言的数组逆序,很实用的,可以下载试试,哈哈哈哈哈哈哈
在数据结构中,字符串通常被看作是字符数组,而字符串逆序就是将字符数组中的元素顺序反转。这个过程可以通过多种方式实现,包括但不限于以下几种方法: 1. **双指针法**: - 初始化两个指针,一个在字符串开头,...
本知识点将围绕如何进行字符串反转以及把整个字符串逆序来进行讲解。首先,字符串反转是编程中常见的问题,常常用于各类笔试和面试中。而字符串逆序则是在反转的基础上,进一步处理,让整个字符串的顺序完全颠倒。 ...
本程序旨在通过指针实现字符串的逆序和调序输出,这两个概念是字符串操作中的常见技巧。 逆序输出字符串是指将字符串中的字符顺序反转,例如原字符串"hello"逆序后变为"olleh"。在C语言中,我们可以用指针来达到这...
函数实现字符串逆序pta数组逆序,不使用字符串函数,只传递数组首元素地址函数接口定义:void f( char *p );函数f对p指向的字符串进行逆序操作。要求函数f中不能定义任何数组,不能调用任何字符串处理函数。裁判测试...
c语言字符串逆序输出c语言字符串逆序输出+c语言字符串逆序逐行解释c语言字符串逆序输出+c语言字符串逆序逐行解释c语言字符串逆序输出+c语言字符串逆序逐行解释c语言字符串逆序输出+c语言字符串逆序逐行解释c语言字符...
既然我们之前已经学了不少倒序的方法了,今天我们就进入实战,看看在数组中的逆序是如何输出的吧。 将一个数组逆序输出,用第一个与最后一个交换。 #!/usr/bin/python # -*- coding: UTF-8 -*- if __name__ == '__...
要求输入一个字符串,然后实现这个字符串的逆序存放
定义一个新的空字符串或字符数组,用于存储逆序后的字符串。 从原始字符串的最后一个字符开始,依次取出每个字符,并将其添加到新字符串中。 继续往前遍历原始字符串,重复上述步骤,直到将所有字符都添加到新字符串...
分配一个与原字符串等长的字符数组; 反向拷贝一下即可。 char* reverseString(char* s) { //将q指向字符串最后一个字符 char* q = s ; while( *q ) { q++; } q -= 1 ; //分配空间,存储逆序后的字符串...
在CUDA编程中,数组逆序是一项常见的操作,用于数据处理和算法实现。本文将探讨两种不同的实现方式:全局内存版和共享内存版。这两种方法在性能和效率上有显著的差异,尤其是在并行计算环境中。 首先,让我们理解...
### 递归实现字符串逆序 #### 知识点概览 本文将详细介绍如何使用C++中的递归技术来实现字符串的逆序操作。逆序字符串是一个常见的编程问题,在多种场景下都有应用,例如文本处理、算法设计等。通过递归方法解决此...
本示例是基于VC++(Visual C++)的命令行界面(CUI)程序,它展示了如何通过C++语言来实现字符串的逆序。下面我们将详细探讨这个主题。 1. **字符串基础**: 在C++中,字符串可以被表示为字符数组或者`std::string...