.match 的多字节字符问题?

Multibyte character issue with .match?

以下代码是我开始测试在我正在开发的 "Texas Hold Em" 风格游戏中使用的代码。

我的问题是,为什么在 运行 下面的代码中,涉及“♥”的 puts return 是一个“\u”。我确信是这个多字节字符导致了问题,因为在第二个 puts 中,我用字符串数组中的 d 替换了 ♦ 并且它 returned 符合我的预期。见下文:

我的代码:

#! /usr/bin/env ruby
# encoding: utf-8

table_cards = ["|2♥|", "|8♥|", "|6d|", "|6♣|", "|Q♠|"]

# Array of cards

player_1_face_1 = "8"
player_1_suit_1 = "♦"

# Player 1's face and suit of first card he has

player_1_face_2 = "6"
player_1_suit_2 = "♥"

# Player 1's face and suit of second card he has

test_str_1 = /(\D8\D{2})/.match(table_cards.to_s)

# EX: Searching for match between face values on (player 1's |8♦|) and the |8♥| on the table

test_str_2 = /(\D6\D{2})/.match(table_cards.to_s)

# EX: Searching for match between face values on (player 1's |6♥|) and the |6d| on the table

puts "#{test_str_1}"
puts "#{test_str_2}"

放到屏幕上:

|8\u

|6d|

-- 我的目标是获得 return 的第一个看跌期权:|8♥|

我并不是在寻找解决方案(甚至可能没有),而是 "as simple as possible" 解释导致此问题的原因和原因。提前感谢您提供有关这里发生的事情以及我如何实现目标的任何信息。

您看到的“\u”是 Unicode 字符串指示器。

例如Unicode字符'HEAVY BLACK HEART'(U+2764)可以打印成"\u2764".

一个友好的 Unicode 字符列表站点是 http://unicode-table.com/en/sets/

你能在你的 shell 中启动交互式 Ruby 并打印这样的心形吗?

irb
irb> puts "\u2764"
❤

当我 运行 在我的 Ruby 中输入您的代码时,我得到了您期望的答案:

test_str_1 = /(\D8\D{2})/.match(table_cards.to_s)
=> #<MatchData "|8♥|" 1:"|8♥|">

如果您尝试使用更适合您卡片的正则表达式会怎样?

 test_str_1 = /(\|8[♥♦♣♠]\|)/.match(table_cards.to_s)

在您的示例输出中,您没有看到您想要的 Unicode 心形符号。相反,您的输出打印的是 Unicode 起始符“\u”,但随后不打印预期字符串的其余部分,即“2764”。

  • 请参阅 Tin Man 描述您的控制台编码的评论。如果他是正确的,那么我希望更具体的正则表达式会成功,但仍然打印出错误的输出。

  • 请参阅 David Knipe 的评论,该评论说它看起来像 t运行cated 因为正则表达式只匹配 4 个字符。如果他是正确的,那么我希望更具体的正则表达式能够成功并打印出正确的输出。

(此答案的其余部分是 Unix 的典型答案;如果您使用的是 Windows,请忽略此处的其余部分...)

要显示您的系统语言设置,请在 shell:

中尝试此操作
echo $LC_ALL
echo $LC_CTYPE

如果它们不是 "UTF-8" 或类似的东西,请在您的 shell:

中试试这个
export LC_ALL=en_US.UTF-8
export LC_CTYPE=en_US.UTF-8

然后重新运行你的代码——一定要使用相同的shell。

如果这可行,并且您想永久保留,一种方法是在此处添加:

# /etc/environment
LC_ALL=en_US.UTF-8
LC_CTYPE=en_US.UTF-8

然后从您的 .bashrc 或 .zshrc 或您使用的任何 shell 启动文件获取该文件。