簡體   English   中英

按 Ruby 中的字符集對字符串進行分區/拆分

[英]Partition/split a string by character set in Ruby

如何在我的字符串中分隔不同的字符集? 例如,如果我有這些字符集:

[a-z]
[A-Z]
[0-9]
[\s]
{everything else}

這個輸入:

thisISaTEST***1234pie

然后我想分隔不同的字符集,例如,如果我使用換行符作為分隔符:

this
IS
a
TEST
***
1234
pie

我已經嘗試過這個正則表達式,並具有積極的前瞻性:

'thisISaTEST***1234pie'.gsub(/(?=[a-z]+|[A-Z]+|[0-9]+|[\s]+)/, "\n")

但顯然+ s 並不貪婪,因為我得到:

t
h
# (snip)...
S
T***
1
# (snip)...
e

我剪掉了不相關的部分,但正如你所看到的,每個字符都被算作自己的字符集,除了{everything else}字符集。

我怎樣才能做到這一點? 它不一定必須是正則表達式。 將它們拆分成一個數組也可以。

困難的部分是匹配與正則表達式其余部分不匹配的任何內容。 忘記這一點,想辦法將不匹配的部分與匹配的部分混合在一起。

"thisISaTEST***1234pie"
.split(/([a-z]+|[A-Z]+|\d+|\s+)/).reject(&:empty?)
# => ["this", "IS", "a", "TEST", "***", "1234", "pie"]

在 ASCII 字符集中,除了字母數字和空格之外,還有 32 個“標點”字符,它們與屬性結構\\p{punct}匹配。

要將字符串拆分為單個類別的序列,您可以編寫

str = 'thisISaTEST***1234pie'
p str.scan(/\G(?:[a-z]+|[A-Z]+|\d+|\s+|[\p{punct}]+)/)

輸出

["this", "IS", "a", "TEST", "***", "1234", "pie"]

或者,如果您的字符串包含 ASCII 集之外的字符,您可以按照屬性編寫整個內容,如下所示

p str.scan(/\G(?:\p{lower}+|\p{upper}+|\p{digit}+|\p{space}|[^\p{alnum}\p{space}]+)/)

這里有兩個解決方案。

String#scan使用正則表達式

str = "thisISa\n TEST*$*1234pie"
r = /[a-z]+|[A-Z]+|\d+|\s+|[^a-zA-Z\d\s]+/
str.scan r
  #=> ["this", "IS", "a", "\n ", "TEST", "*$*", "1234", "pie"]

由於^[^a-zA-Z\\d\\s]的開頭,該字符類匹配字母(小寫和大寫)、數字和空格以外的任何字符。

使用Enumerable#slice_when 1

首先是一個輔助方法:

def type(c)
  case c
  when /[a-z]/ then 0
  when /[A-Z]/ then 1
  when /\d/    then 2
  when /\s/    then 3
  else              4
  end
end

例如,

type "f"   #=> 0
type "P"   #=> 1
type "3"   #=> 2
type "\n"  #=> 3
type "*"   #=> 4    

然后

str.each_char.slice_when { |c1,c2| type(c1) != type(c2) }.map(&:join)
  #=> ["this", "IS", "a", "TEST", "***", "1234", "pie"]

1. slich_when在 Ruby v2.4 中首次亮相。

非單詞、非空格字符可以用[^\\w\\s]覆蓋,因此:

"thisISaTEST***1234pie".scan /[a-z]+|[A-Z]+|\d+|\s+|[^\w\s]+/
#=> ["this", "IS", "a", "TEST", "***", "1234", "pie"]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM