36、Ruby编程中的正则表达式、数值运算、日期时间处理

Ruby编程中的正则表达式、数值运算、日期时间处理

1. 正则表达式

在Ruby 1.9中,正则表达式有很多强大的特性。
- 命名捕获与局部变量 :当包含命名捕获的正则表达式直接出现在 =~ 运算符左侧时,捕获组的名称会被当作局部变量,匹配的文本会赋值给这些变量。若匹配失败,变量会被赋值为 nil 。示例代码如下:

# Ruby 1.9 only
if /(?<lang>\w+) (?<ver>\d+\.(\d+)+) (?<review>\w+)/ =~ "Ruby 1.9 rules!"
  lang     # => "Ruby"
  ver      # => "1.9"
  review   # => "rules"
end

不过,只有正则表达式直接写在代码里时才会有这种特殊行为。若模式存储在变量、常量中,或由方法返回,或者模式在 =~ 运算符右侧,就不会进行这种特殊的局部变量赋值。若Ruby以 -w 选项启动, =~ 运算符覆盖已定义变量时会发出警告。
- match方法 :除了 =~ 运算符, Regexp String 类还定义了 match 方法。它与匹配运算符类似,但不是返回匹配的索引,而是返回 MatchData 对象,若未找到匹配文本则返回 nil 。在Ruby 1.9中,还能给 match 调用关联一个代码块。若未找到匹配,代码块会被忽略, match 返回 nil ;若找到匹配, MatchData 对象会传递给代码块, match 方法返回代码块的返回值。示例如下:

if data = pattern.match(text)  # Or: data = text.match(pattern)
  handle_match(data)
end
# Ruby 1.9更简洁的写法
pattern.match(text) {|data| handle_match(data) }

此外,Ruby 1.9的 match 方法还可接受一个整数作为第二个参数,指定搜索的起始位置。
- 全局匹配数据变量 :Ruby采用了Perl的正则表达式语法,每次匹配后会设置特殊的全局变量。这些变量对Perl程序员可能有用,对非Perl程序员可能不太易读。相关变量总结如下表:
| Global | English | Alternative |
| ---- | ---- | ---- |
| $~ | $LAST_MATCH_INFO | Regexp.last_match |
| $& | $MATCH | Regexp.last_match[0] |
| $` | $PREMATCH | Regexp.last_match.pre_match |
| $’ | $POSTMATCH | Regexp.last_match.post_match |
| $1 | none | Regexp.last_match[1] |
| $2, etc. | none | Regexp.last_match[2], etc. |
| $+ | $LAST_PAREN_MATCH | Regexp.last_match[-1] |

$~ 是最重要的变量,其他变量都由它派生。若将 $~ 设为 MatchData 对象,其他特殊全局变量的值会改变。其他全局变量是只读的,不能直接设置。并且, $~ 及其派生变量都是线程局部和方法局部的。
- 字符串模式匹配 String 类定义了很多接受 Regexp 参数的方法。
- 索引操作 :用正则表达式索引字符串,会返回匹配模式的部分。若正则表达式后跟着整数,会返回 MatchData 的对应元素。示例:

"ruby123"[/\d+/]              # "123"
"ruby123"[/([a-z]+)(\d+)/,1]  # "ruby"
"ruby123"[/([a-z]+)(\d+)/,2]  # "123"
- **slice方法**:是字符串索引运算符`[]`的同义词。`slice!`变体返回与`slice`相同的值,还会从字符串中删除返回的子字符串。示例:
r = "ruby123"
r.slice!(/\d+/)  # Returns "123", changes r to "ruby"
- **split方法**:用字符串或正则表达式作为分隔符,将字符串拆分成子字符串数组。示例:
s = "one, two, three"
s.split            # ["one,","two,","three"]: whitespace delimiter by default
s.split(", ")      # ["one","two","three"]: hardcoded delimiter
s.split(/\s*,\s*/) # ["one","two","three"]: space is optional around comma
- **index方法**:在字符串中搜索字符、子字符串或模式,返回起始索引。使用`Regexp`参数时,与`=~`运算符类似,但还允许第二个参数指定搜索起始的字符位置,可找到除第一个之外的匹配。示例:
text = "hello world"
pattern = /l/
first = text.index(pattern)       # 2: first match starts at char 2
n = Regexp.last_match.end(0)      # 3: end position of first match
second = text.index(pattern, n)   # 3: search again from there
last = text.rindex(pattern)       # 9: rindex searches backward from end
  • 搜索与替换 :一些重要的 String 方法用于搜索和替换,如 sub (替换第一个匹配)和 gsub (替换所有匹配),以及它们的原地变体 sub! gsub! 。这些方法使用正则表达式模式进行搜索替换操作。示例如下:
phone = gets                    # Read a phone number
phone.sub!(/#.*$/, "")          # Delete Ruby-style comments
phone.gsub!(/\D/, "")           # Remove anything other than digits

这些方法也可用普通字符串作为要替换的文本,但正则表达式更灵活。替换字符串可以引用捕获组匹配的文本,也可引用其他文本。还可传入代码块动态计算替换字符串。示例:

text = "RUBY Java perl PyThOn"         # Text to modify
lang = /ruby|java|perl|python/i        # Pattern to match
text.gsub!(lang) {|l| l.capitalize }   # Fix capitalization
  • 正则表达式编码 :在Ruby 1.9中, Regexp 对象和字符串一样有编码方法。可用修饰符显式指定正则表达式的编码,如 u 表示UTF - 8, s 表示SJIS, e 表示EUC - JP, n 表示无。若不指定编码,使用源编码;若正则表达式所有字符都是ASCII,即使源编码是ASCII的超集,也使用ASCII。若尝试匹配编码不兼容的模式和字符串,Ruby 1.9的模式匹配操作会抛出异常。 fixed_encoding? 方法可判断 Regexp 是否有非ASCII编码。
2. 数值与数学运算
  • 数值方法 Numeric 及其子类定义了很多有用的谓词,用于确定数字的类或测试其值。部分谓词仅适用于 Float 值,部分仅适用于 Integer 值。示例如下:
# General Predicates
0.zero?        # => true (is this number zero?)
1.0.zero?      # => false
0.0.nonzero?   # => nil (works like false)
1.nonzero?     # => 1 (works like true)
1.integer?     # => true
1.0.integer?   # => false
1.scalar?      # => false: not a complex number. Ruby 1.9.
1.0.scalar?    # => false: not a complex number. Ruby 1.9.
Complex(1,2).scalar? # => true: a complex number. requires 'complex'.
# Integer predicates
0.even?        # => true (Ruby 1.9)
0.odd?         # => false
# Float predicates
ZERO, INF, NAN = 0.0, 1.0/0.0, 0.0/0.0  # Constants for testing
ZERO.finite?   # => true: is this number finite?
INF.finite?    # => false
NAN.finite?    # => false
ZERO.infinite? # => nil: is this number infinite? Positive or negative?
INF.infinite?  # => 1
-INF.infinite? # => -1
NAN.infinite?  # => nil
ZERO.nan?      # => false: is this number not-a-number?
INF.nan?       # => false
NAN.nan?       # => true

Float 类定义了一些用于数字舍入的方法,多数方法 Numeric 类也有定义,可用于任何类型的数字。示例:

# Rounding methods
1.1.ceil     # =>  2: ceiling: smallest integer >= its argument
-1.1.ceil    # => -1: ceiling: smallest integer >= its argument
1.9.floor    # =>  1: floor: largest integer <= its argument
-1.9.floor   # => -2: floor: largest integer <= its argument
1.1.round    # =>  1: round to nearest integer
0.5.round    # =>  1: round toward infinity when halfway between integers 
-0.5.round   # => -1: or round toward negative infinity
1.1.truncate # =>  1: chop off fractional part: round toward zero
-1.1.to_i    # => -1: synonym for truncate

Float 类还定义了其他一些方法和常量,如绝对值、符号和一些常量:

# Absolute value and sign
-2.0.abs     # => 2.0: absolute value
-2.0<=>0.0   # => -1: use <=> operator to compute sign of a number
# Constants
Float::MAX     # => 1.79769313486232e+308: may be platform dependent
Float::MIN     # => 2.2250738585072e-308
Float::EPSILON # => 2.22044604925031e-16: difference between adjacent floats
  • Math模块 Math 模块定义了常量 PI E ,以及三角函数、对数等方法。这些方法是“模块函数”,可通过 Math 命名空间调用,也可包含后像全局函数一样调用。示例如下:
# Constants
Math::PI               # => 3.14159265358979
Math::E                # => 2.71828182845905
# Roots
Math.sqrt(25.0)        # => 5.0: square root
27.0**(1.0/3.0)        # => 3.0: cube root computed with ** operator
# Logarithms
Math.log10(100.0)      # => 2.0: base-10 logarithm
Math.log(Math::E**3)   # => 3.0: natural (base-e) logarithm
Math.log2(8)           # => 3.0: base-2 logarithm. Ruby 1.9 and later.
Math.log(16, 4)        # => 2.0: 2nd arg to log() is the base. Ruby 1.9.
Math.exp(2)            # => 7.38905609893065": same as Math::E**2
# Trigonometry
include Math           # Save typing: we can now omit Math prefix.
sin(PI/2)              # => 1.0: sine. Argument is in radians, not degrees.
cos(0)                 # => 1.0: cosine.
tan(PI/4)              # => 1.0: tangent.
asin(1.0)/PI           # => 0.5: arcsine. See also acos and atan.
sinh(0)                # => 0.0: hyperbolic sine. Also cosh, tanh.
asinh(1.0)             # => 0.0: inverse sinh. Also acosh, atanh.
# Convert cartesian point (x,y) to polar coordinates (theta, r)
theta = atan2(y,x)     # Angle between X axis and line (0,0)-(x,y)
r = hypot(x,y)         # Hypotenuse: sqrt(x**2 + y**2)
# Decompose float x into fraction f and exponent e, such that x = f*2**e
f,e = frexp(1024.0)    # => [0.5, 11]
x = ldexp(f, e)        # => 1024: compute x = f*2**e
# Error function
erf(0.0)               # => 0.0: error function
erfc(0.0)              # => 1.0: 1-erf(x): complementary error function
  • 十进制算术 :标准库中的 BigDecimal 类是 Float 的有用替代,尤其在金融计算中,可避免二进制浮点算术固有的舍入误差。 BigDecimal 对象可有无限多有效数字和几乎无限的大小,使用十进制算术,能精确控制舍入模式。示例代码如下:
require "bigdecimal"      # Load standard library
dime = BigDecimal("0.1")  # Pass a string to constructor, not a Float
4*dime-3*dime == dime     # true with BigDecimal, but false if we use Float
# Compute monthly interest payments on a mortgage with BigDecimal.
# Use "Banker's Rounding" mode, and limit computations to 20 digits
BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
BigDecimal.limit(20)
principal = BigDecimal("200000")  # Always pass strings to constructor
apr = BigDecimal("6.5")           # Annual percentage rate interest
years = 30                        # Term of mortgage in years
payments = years*12               # 12 monthly payments in a year
interest = apr/100/12             # Convert APR to monthly fraction
x = (interest+1)**payments        # Note exponentiation with BigDecimal
monthly = (principal * interest * x)/(x-1)  # Compute monthly payment
monthly = monthly.round(2)        # Round to two decimal places
monthly = monthly.to_s("f")       # Convert to human-readable string
  • 复数 :标准库中的 Complex 类可表示和操作复数。它和 BigDecimal 类一样,定义了所有常规算术运算符,还重新定义了 Math 模块的方法,使其能处理复数。示例如下:
require "complex"           # Complex is part of the standard library
c = Complex(0.5,-0.2)       # .5-.2i.  
z = Complex.new(0.0, 0.0)   # Complex.new also works, but is not required
10.times { z = z*z + c }    # Iteration for computing Julia set fractals
magnitude = z.abs           # Magnitude of a complex number
x = Math.sin(z)             # Trig functions work with Complex numbers
Math.sqrt(-1.0).to_s        # => "1.0i": square root of -1
Math.sqrt(-1.0)==Complex::I # => true
  • 有理数 :标准库中的 Rational 类表示有理数,定义了有理数的算术运算符。与 mathn 库配合使用效果最佳, mathn 库重新定义整数除法以产生有理数,还做了很多其他事情来“统一”Ruby算术,使 Integer Rational Complex 类协同工作良好。示例如下:
require "rational"           # Load the library
penny = Rational(1, 100)     # A penny is 1/100th
require "mathn"              # Makes integer division produce Rational values
nickel = 5/100
dime = 10/100
quarter = 1/4
change = 2*quarter + 3*penny # Rational result: 53/100
(1/2 * 1/3).to_s             # "1/6": mathn prints Rationals as fractions
  • 向量和矩阵 :矩阵库定义了 Matrix Vector 类来表示数字矩阵和向量,以及执行算术运算的运算符。以下示例代码使用 Vector 类表示二维点,使用2×2矩阵对象表示点的缩放和旋转变换:
require "matrix"
# Represent the point (1,1) as the vector [1,1]
unit = Vector[1,1]
# The identity transformation matrix
identity = Matrix.identity(2)  # 2x2 matrix
identity*unit == unit          # true: no transformation
# This matrix scales a point by sx,sy
sx,sy = 2.0, 3.0;
scale = Matrix[[sx,0], [0, sy]]
scale*unit             # => [2.0, 3.0]: scaled point
# This matrix rotates counterclockwise around the origin
theta = Math::PI/2     # 90 degrees
rotate = Matrix[[Math.cos(theta), -Math.sin(theta)],
                [Math.sin(theta),  Math.cos(theta)]]
rotate*unit            # [-1.0, 1.0]: 90 degree rotation
# Two transformations in one
scale * (rotate*unit)  # [-2.0, 3.0]
  • 随机数 :Ruby用全局 Kernel.rand 函数生成随机数。无参数时,返回一个大于等于0.0且小于1.0的伪随机 Float ;有整数参数 max 时,返回一个大于等于0且小于 max 的伪随机整数。若需要可重复的伪随机数序列,可用已知值为随机数生成器设置种子。示例如下:
rand       # => 0.964395196505186
rand       # => 0.390523655919935
rand(100)  # => 81
rand(100)  # => 32
srand(0)                # Known seed
[rand(100),rand(100)]   # => [44,47]: pseudorandom sequence
srand(0)                # Reset the seed to repeat the sequence
[rand(100),rand(100)]   # => [44,47]
3. 日期与时间处理
  • 创建时间对象 Time 类表示日期和时间,是操作系统提供的系统日期和时间功能的薄封装。在某些平台上,可能无法表示1970年之前或2038年之后的日期。可通过以下方式创建 Time 对象:
Time.now        # Returns a time object that represents the current time
Time.new        # A synonym for Time.now
Time.local(2007, 7, 8)          # July 8, 2007
Time.local(2007, 7, 8, 9, 10)   # July 8, 2007, 09:10am, local time
Time.utc(2007, 7, 8, 9, 10)     # July 8, 2007, 09:10 UTC
Time.gm(2007, 7, 8, 9, 10, 11)  # July 8, 2007, 09:10:11 GMT (same as UTC)
  • 时间组件 :可获取 Time 对象的各个组件,如年、月、日、时、分、秒等。示例如下:
t = Time.utc(2000, 12, 31, 23, 59, 59, 999999)
t.year    # => 2000
t.month   # => 12: December
t.day     # => 31
t.wday    # => 0: day of week: 0 is Sunday
t.yday    # => 366: day of year: 2000 was a leap year
t.hour    # => 23: 24-hour clock
t.min     # => 59
t.sec     # => 59
t.usec    # => 999999: microseconds, not milliseconds
t.zone    # => "UTC": timezone name

还可将所有组件获取到一个数组中,该数组可传递给 Time.local Time.utc

values = t.to_a    # => [59, 59, 23, 31, 12, 2000, 0, 366, false, "UTC"]
values[5] += 1     # Increment the year
Time.utc(*values)  # => Mon Dec 31 23:59:59 UTC 2001
  • 时区和夏令时 :可获取 Time 对象的时区信息,进行时区转换,判断是否为夏令时。示例如下:
t.zone       # => "UTC": return the timezone
t.utc?       # => true: t is in UTC time zone
t.utc_offset # => 0: UTC is 0 seconds offset from UTC
t.localtime  # Convert to local timezone. Mutates the Time object!
t.zone       # => "PST" (or whatever your timezone is)
t.utc?       # => false
t.utc_offset # => -28800: 8 hours before UTC
t.gmtime     # Convert back to UTC. Another mutator.
t.getlocal   # Return a new Time object in local zone
t.getutc     # Return a new Time object in UTC
t.isdst      # => false: UTC does not have DST. Note no ?.
t.getlocal.isdst # => false: no daylight savings time in winter.
  • 星期几的谓词 :在Ruby 1.9中,有星期几的谓词方法,如 sunday? monday? 等。示例:
t.sunday?    # => true
t.monday?    # => false
  • 日期和时间格式化 :可使用 to_s ctime strftime 方法格式化日期和时间。示例如下:
t.to_s       # => "Sun Dec 31 23:59:59 UTC 2000": Ruby 1.8
t.to_s       # => "2000-12-31 23:59:59 UTC": Ruby 1.9 uses ISO-8601
t.ctime      # => "Sun Dec 31 23:59:59 2000": another basic format
# strftime interpolates date and time components into a template string
# Locale-independent formatting
t.strftime("%Y-%m-%d %H:%M:%S") # => "2000-12-31 23:59:59": ISO-8601 format
t.strftime("%H:%M")             # => "23:59": 24-hour time
t.strftime("%I:%M %p")          # => "11:59 PM": 12-hour clock
# Locale-dependent formats
t.strftime("%A, %B %d")         # => "Sunday, December 31"
t.strftime("%a, %b %d %y")      # => "Sun, Dec 31 00": 2-digit year
t.strftime("%x")                # => "12/31/00": locale-dependent format
t.strftime("%X")                # => "23:59:59"
t.strftime("%c")                # same as ctime
  • 日期和时间解析 :可使用 parsedate 库解析日期和时间字符串。示例如下:
require 'parsedate'    # A versatile date/time parsing library
include ParseDate      # Include parsedate() as a global function
datestring = "2001-01-01"
values = parsedate(datestring)  # [2001, 1, 1, nil, nil, nil, nil, nil]
t = Time.local(*values)         # => Mon Jan 01 00:00:00 -0800 2001
s = t.ctime                     # => "Mon Jan  1 00:00:00 2001"
Time.local(*parsedate(s))==t    # => true
s = "2001-01-01 00:00:00-0500"  # midnight in New York
v = parsedate(s)                # => [2001, 1, 1, 0, 0, 0, "-0500", nil]
t = Time.local(*v)              # Loses time zone information!
  • 时间算术和比较 :可进行时间的加减运算,比较时间的先后顺序。示例如下:
now = Time.now          # Current time
past = now - 10         # 10 seconds ago. Time - number => Time
future = now + 10       # 10 seconds from now Time + number => Time
future - now            # => 10  Time - Time => number of seconds
# Time comparisons
past <=> future         # => -1
past < future           # => true
now >= future           # => false
now == now              # => true
  • 时间单位辅助方法 :可定义辅助方法处理非秒的时间单位。示例如下:
class Numeric
  # Convert time intervals to seconds
  def milliseconds; self/1000.0; end
  def seconds; self; end
  def minutes; self*60; end
  def hours; self*60*60; end
  def days; self*60*60*24; end
  def weeks; self*60*60*24*7; end
  # Convert seconds to other intervals
  def to_milliseconds; self*1000; end
  def to_seconds; self; end
  def to_minutes; self/60.0; end
  def to_hours; self/(60*60.0); end
  def to_days; self/(60*60*24.0); end
  def to_weeks; self/(60*60*24*7.0); end
end
expires = now + 10.days     # 10 days from now
expires - now               # => 864000.0 seconds
(expires - now).to_hours    # => 240.0 hours
  • 时间内部表示 Time 对象内部表示为自(平台相关的)纪元以来的秒数,可进行相互转换。示例如下:
t = Time.now.to_i    # => 1184036194 seconds since epoch
Time.at(t)           # => seconds since epoch to Time object
t = Time.now.to_f    # => 1184036322.90872: includes 908720 microseconds
Time.at(0)           # => Wed Dec 31 16:00:00 -0800 1969: epoch in local time

综上所述,Ruby在正则表达式、数值运算和日期时间处理方面提供了丰富的功能和灵活的操作方式,能满足各种编程需求。在实际应用中,可根据具体场景选择合适的方法和类来完成任务。

Ruby编程中的正则表达式、数值运算、日期时间处理

4. 总结与实践建议
  • 正则表达式总结

    • 正则表达式在Ruby中功能强大,命名捕获与局部变量的特性让代码更具可读性和简洁性,但要注意其使用条件,即正则表达式需直接写在代码中。
    • match 方法提供了更灵活的匹配结果获取方式,在Ruby 1.9中还能结合代码块使用。
    • 全局匹配数据变量虽然对非Perl程序员不太友好,但在特定场景下有其用途。
    • 字符串模式匹配和搜索替换方法为处理字符串提供了丰富的手段,正则表达式的编码处理也需要根据实际情况进行设置。

    实践建议
    - 在使用命名捕获时,确保正则表达式的写法符合预期,避免因模式存储方式导致局部变量赋值失败。
    - 使用 match 方法结合代码块处理匹配结果,让代码更简洁易读。
    - 在进行搜索替换操作时,优先考虑使用正则表达式,利用其灵活性处理复杂的替换需求。

  • 数值与数学运算总结

    • Numeric 及其子类的谓词方法方便了对数字类型和值的判断, Float 类的舍入方法和常量为数值处理提供了便利。
    • Math 模块包含了丰富的数学函数,可用于各种数学计算。
    • BigDecimal Complex Rational 类分别适用于处理十进制数、复数和有理数,与 mathn 库结合使用能让整数除法产生有理数,使不同数值类型协同工作。
    • 矩阵库中的 Matrix Vector 类可用于处理线性代数相关的计算。
    • Kernel.rand 函数可生成随机数,通过设置种子可实现可重复的随机序列。

    实践建议
    - 在金融计算等对精度要求较高的场景中,使用 BigDecimal 类避免舍入误差。
    - 处理复数和有理数时,合理使用相应的类和库,提高代码的准确性和可读性。
    - 在需要进行线性代数计算时,使用 Matrix Vector 类简化代码。
    - 在测试环境中,使用已知种子生成可重复的随机数序列,方便调试。

  • 日期与时间处理总结

    • Time 类可用于创建和操作日期时间对象,能获取时间的各个组件,进行时区转换和夏令时判断。
    • 日期和时间的格式化和解析方法提供了灵活的时间表示和处理方式。
    • 时间的算术和比较操作方便了对时间的计算和判断,辅助方法可处理不同时间单位。
    • Time 对象内部表示为自纪元以来的秒数,可进行相互转换。

    实践建议
    - 在创建 Time 对象时,根据需求选择合适的方法,如 Time.now 获取当前时间, Time.local Time.utc 创建指定时间。
    - 在处理不同时区的时间时,注意时区转换和夏令时的影响。
    - 使用 strftime 方法进行日期时间格式化,根据需要选择合适的格式字符串。
    - 在进行时间计算时,使用辅助方法处理不同时间单位,提高代码的可读性。

5. 流程图示例

以下是一个简单的Ruby正则表达式搜索替换流程图:

graph TD;
    A[开始] --> B[定义字符串和正则表达式模式];
    B --> C[选择搜索替换方法(sub/gsub/sub!/gsub!)];
    C --> D{是否使用代码块};
    D -- 是 --> E[定义代码块处理匹配结果];
    D -- 否 --> F[定义替换字符串];
    E --> G[执行搜索替换操作];
    F --> G;
    G --> H[输出结果];
    H --> I[结束];
6. 总结

Ruby在正则表达式、数值运算和日期时间处理方面提供了丰富的功能和灵活的操作方式。通过合理运用这些功能,可以高效地完成各种编程任务。在实际开发中,需要根据具体需求选择合适的方法和类,同时注意一些细节,如正则表达式的编码、数值计算的精度等。希望本文能帮助你更好地掌握Ruby在这些方面的应用,提升编程效率和代码质量。

7. 常见问题解答
  • 正则表达式相关问题

    • :为什么使用双引号替换字符串时, $& 等变量不能正确插值?
      :因为在将字符串传递给 gsub 等方法之前,字符串插值就已经执行了,此时模式还未匹配,所以这些变量可能未定义或保存着上一次匹配的值。建议使用 \& 等语法或在Ruby 1.9中使用 \k 命名回引用语法。
    • :正则表达式存储在变量中时,为什么 =~ 运算符不进行局部变量赋值?
      :这种特殊的局部变量赋值行为只在正则表达式直接写在代码中时才会发生,存储在变量、常量或由方法返回的模式不具备此特性。
  • 数值运算相关问题

    • BigDecimal 类为什么要传入字符串而不是浮点数?
      :传入浮点数会引入二进制浮点算术的舍入误差,而传入字符串可以精确表示十进制数,避免误差。
    • mathn 库的作用是什么?
      mathn 库重新定义了整数除法,使其产生有理数,还做了一些其他操作来统一Ruby算术,让不同数值类型协同工作。
  • 日期时间处理相关问题

    • :为什么 Time.local 处理包含时区信息的字符串时会丢失时区信息?
      Time.local 方法主要用于创建本地时间对象,它不处理时区信息的解析和保存,若需要处理时区信息,可考虑使用其他日期时间库。
    • :如何处理不同时区的时间?
      :可以使用 Time 对象的 utc? utc_offset localtime gmtime 等方法进行时区转换,也可以使用第三方日期时间库来更方便地处理时区问题。

通过对这些常见问题的解答,希望能帮助你更好地理解和使用Ruby在正则表达式、数值运算和日期时间处理方面的功能。在实际编程中,遇到问题时可参考这些解答,提高解决问题的效率。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值