【问题标题】:How to extract integer after "=" sign using ruby如何使用ruby在“=”符号后提取整数
【发布时间】:2015-10-29 11:39:31
【问题描述】:

我正在尝试提取mrp=talktime= 之后的整数。

var i=0;
var recharge=[];
var recharge_text=[];
var recharge_String="";
var mrp="";
var talktime="";
var validity="";
var mode="";mrp='1100';
talktime='1200.00';
validity='NA';
mode='E-Recharge';
if(typeof String.prototype.trim !== 'function') {
 String.prototype.trim = function() {
 return this.replace(/^ +| +$/g, '');
 }
}
mrp=mrp.trim();
if(isNaN(mrp))
{
recharge_text.push({MRP:mrp, Talktime:talktime, Validity:validity ,Mode:mode});
}
else
{
mrp=parseInt(mrp);
recharge.push({MRP:mrp, Talktime:talktime, Validity:validity ,Mode:mode});
}
mrp='2200';
talktime='2400.00';

我已经从网页中提取了上述文本,但我不知道如何单独提取该特定部分。

【问题讨论】:

  • hari,您能解释一下您所说的 extract 是什么意思吗?这样做的目的是什么?我刚刚重新格式化了你提供的代码,但我现在感觉你正在抓取信息,所以如果你能澄清一下就好了。
  • 使用.to_i从字符串中获取int
  • 欢迎来到 Stack Overflow。我们希望看到您尝试解决问题。 Stack Overflow 不是“给我代码”站点,而是“我们帮助您调试代码”站点。请添加您为解决此问题而编写的代码的最小示例,我们很乐意提供帮助。另外,您的问题定义不明确。您想要的值在捕获的文本中出现多次。你想要哪些次出现?第一个,最后一个,全部?请编辑您的问题并填空。

标签: ruby-on-rails ruby


【解决方案1】:

您可以使用正则表达式来解析字符串并提取其中的一部分:

my_text = "blablabla" #just imagine that this is your text
regex_mrp = /mrp='(.+?)';/ #extracts whatever is between single quotes after mrp
regex_talktime = /talktime='(.+?)';/ #extracts whatever is between single quotes after talktime

mrp = my_text.match(regex_mrp)[1].to_i #gets the match, and converts to integer
talktime = my_text.match(regex_talktime)[1].to_f #gets the match, and converts to float

这里是正则表达式语法的快速参考:https://msdn.microsoft.com/en-us/library/az24scfc(v=vs.110).aspx

【讨论】:

  • 问题是,OP 的文本中有多次出现的值。哪个是正确的?没有这些信息就无法给出答案,因为我们只是在黑暗中拍摄。
  • @theTinMan,老兄,我想提取所有出现的事件。
【解决方案2】:

我会这样做:

string = <<EOT
var i=0;
var recharge=[];
var recharge_text=[];
var recharge_String="";
var mrp="";
var talktime="";
var validity="";
var mode="";mrp='1100';
talktime='1200.00';
validity='NA';
mode='E-Recharge';
if(typeof String.prototype.trim !== 'function') {
String.prototype.trim = function() {
return this.replace(/^ +| +$/g, '');
}
}
mrp=mrp.trim();
if(isNaN(mrp))
{
recharge_text.push({MRP:mrp, Talktime:talktime, Validity:validity ,Mode:mode});
}
else
{
mrp=parseInt(mrp);
recharge.push({MRP:mrp, Talktime:talktime, Validity:validity ,Mode:mode});
}
mrp='2200';
talktime='2400.00';
EOT

hits = string.scan(/(?:mrp|talktime)='[\d.]+'/)
# => ["mrp='1100'", "talktime='1200.00'", "mrp='2200'", "talktime='2400.00'"]

这为我们提供了一个使用 scan 的命中数组,其中模式 /(?:mrp|talktime)='[\d.]+'/ 在字符串中匹配。弄清楚该模式的工作原理留给用户作为练习,但 Ruby 的 Regexp 文档解释了这一切。

清理它以使其更有用:

hash = hits.map{ |s|
  str, val = s.split('=')
  [str, val.delete("'")]
}.each_with_object(Hash.new { |h, k| h[k] = [] }){ |(str, val), h| h[str] << val }

您还需要了解each_with_object 以及Hash.new 发生了什么,因为这些是在 Ruby 中学习的重要概念。

此时,hash 是数组的散列:

hash # => {"mrp"=>["1100", "2200"], "talktime"=>["1200.00", "2400.00"]}

您可以轻松提取特定变量的值,并在需要时将它们关联起来。


如果我在“=”符号旁边得到一个字符串而不是整数怎么办?

...

string.scan(/(?:tariff)='[\p{Print}]+'/)

了解模式在做什么很重要。正则表达式引擎有一些陷阱会极大地影响搜索速度,因此在不了解它们的作用的情况下不加选择地乱扔东西可能会非常昂贵。

使用(?:...) 时,您正在创建一个非捕获组。当你只有一个匹配的项目时,它不是必需的,也不是特别理想的,因为它使引擎做更多的工作。我唯一会这样做的时候是当我需要回顾捕获的内容时,但由于你只有一个可能的东西,它会匹配成为一个有争议的问题。因此,您的模式应简化为:

/tariff='[\p{Print}]+'/

使用时会导致:

%(tariff='abcdef abc a').scan(/tariff='[\p{Print}]+'/) 
# => ["tariff='abcdef abc a'"]

如果您想捕获分配的字符串的所有非空出现,这比您正在做的更容易。我会使用类似的东西:

%(tariff='abcdef abc a').scan(/tariff='.+'/) 
# => ["tariff='abcdef abc a'"]

%(tariff='abcdef abc a').scan(/tariff='[^']+'/) 
# => ["tariff='abcdef abc a'"]

第二个更严格,并且可能更安全,因为它不会被包含多个单引号的行所欺骗:

%(tariff='abcdef abc a', 'foo').scan(/tariff='.+'/) 
# => ["tariff='abcdef abc a', 'foo'"]

%(tariff='abcdef abc a', 'foo').scan(/tariff='[^']+'/) 
# => ["tariff='abcdef abc a'"]

为什么会这样,你自己想办法。

【讨论】:

  • 老兄,如果我在“=”符号旁边得到一个字符串而不是整数怎么办??假设 string=
  • 知道了,伙计。这个有效, string.scan(/(?:tariff)='[\p{Print}]+'/) 。
  • @hari,作为写作风格的说明,最好不要说“dude”,除了偶尔幽默。全世界都可以看到评论,包括潜在的雇主;扔掉 cmets 并展示自己时要考虑的事情。
猜你喜欢
  • 1970-01-01
  • 2011-04-12
  • 1970-01-01
  • 2011-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-29
相关资源
最近更新 更多