2017-10-11 67 views
0

我“用m钢轨5和Ruby 2.4。我有一个函数如何申请gsub服从功能?

my_function(str1, str2) 

,将返回true或false给两个字符串参数。我想要做的是什么赋予了较大的字符串,例如

"a b c d" 

我想换成两个连续的“字”(由我的定义一个字字符,随后是词边界的序列)与空字符串如果表达式

my_function(str1, str2) 

对于这两个连续单词评估为真。因此,举例来说,如果

my_function("b", "c") 

计算结果为真,我想上面的字符串成为

"a d" 

我该怎么办呢?

编辑:我包括基于汤主的回答输出...

如果我使用

def stuff(line) 
    matches = line.scan(/\b((\S+?)\b.*?\b(\S+?))\b/) 
    matches.each do |full_match, word1, word2| 
     line.delete!(full_match) if word1.eql?("hello") && word2.eql?("world") 
    end 
    end 

和线

"hello world this is a test" 

生成的字符串线是

"tisisatst" 

这不是我所期望的。结果应该是

" this is a test" 

回答

2

编辑:这是一个更新的答案,根据下面的评论。我已将原始答案留在底部。

扫描“两个连续单词”的字符串有点棘手。你最好的选择可能是使用\b锚在一个正则表达式,这标志着一个“单词边界”:

string_to_change = "a b c d" 

matches = string_to_change.scan(/\b((\S+?)\b.*?\b(\S+?))\b/) 
    # => [["a b", "a", "b"], ["c d", "c", "d"]] 

...当第一个字符串是“整个比赛”(包括任何空格或标点符号),其他人是这两个字。

为了打破该正则表达式:

  • \b手段 “单词边界”。我已经放置了两个字符串的每一边的一个。 此解决方案假定str1str2都是单个词。 (如果它们包含空格,那么我不知道你期望什么行为?)
  • \S+?表示“一个或多个非空白字符”。 (非贪婪匹配,所以它会停止匹配第一个字边界)。

然后,您可以从字符串中删除每个“全场比赛”,如果该方法的两个词返回true:

matches.each do |full_match, word1, word2| 
    string_to_change.gsub!(full_match, '') if my_function(word1, word2) 
end 

一个多数民众赞成不占这里的东西(你没有在你的问题中详细说明这一点)是如何处理包含三个或更多单词的字符串。例如,考虑以下因素:

"hello world this is a test" 

假设my_function(word1, word2)回报true只为对:"world", "this""hello", "is"

我上面的代码将看看对:"hello", "world""this", "is""a", "test"。但也许它实际上应该:

  1. 所有对的话,即用左手和右手边匹配所有单词。
  2. 重复删除,即初始对后:"world this"被删除后,该字符串应该被重新扫描,然后"hello is"也应该被删除?

如果需要进一步改进,请在新问题中清楚解释它们(如果您正在努力自己解决问题)。


原来的答复:

str1 = "b" 
str2 = "c" 
string_to_change = "a b c d" 

if my_function(str1, str2) 
    string_to_change.gsub!(/\b#{str1}\b\s+\b#{str2}\b/, "") 
end 

为了打破该正则表达式:

  • \b手段 “单词边界”。我已经放置了两个字符串的每一边的一个。 此解决方案假定str1str2都是单个词。 (如果它们包含空格,那么我不知道你期望什么行为?)
  • \s+表示“一个或多个空格字符”。你可能希望调整它以允许其他标点符号,例如逗号或句号。这个问题的完全通用的解决方案实际上可以是:

string_to_change.gsub!(/\b#{str1}\b.(\B.)*#{str2}\b/, "") 

# Or equivalently: 

string_to_change.gsub!(/\b#{str1}\b(.\B)*.#{str2}\b/, "") 

.(\B.)*代替收集每个字符,一次一个,总是检查它不是一个字的第一个字母(即由非单词边界进行)。

+0

这是一个'if'语句,而不是一个方法。是的你可以。 –

+0

(只要你首先定义'my_function'方法,并使其返回'true'),尝试在控制台中运行它。它工作正常。 –

+0

谢谢你,但你已经在你的解决方案中硬编码了几个东西。我只是列举“b”和“c”为例。有一些参数可能会导致my_function(str1,str2)为true。如果我只给了一长串文字呢?那么我如何才能使逻辑工作? – Dave