Как уточнить разделение символов из цифр в выражении регулярного выражения - PullRequest
1 голос
/ 27 сентября 2019

Я немного устал от регулярных выражений и имею следующую проблему.Ниже мой текст для того, что я пытаюсь отделить.

INVOICE # 2599
INVOICE 0185570
INVOICE: 1739
INVOICE- 45441
INVOICE:# 1234
INVOICE :# 5678

Что мне нужно сделать, это найти два совпадения точно.Например, я хотел бы получить следующее:

[INVOICE#, 2599]
[INVOICE, 0185570]
[INVOICE:, 1739]
[INVOICE-, 45441]
[INVOICE:#, 45441]
[INVOICE:#, 5678]

Пока что у меня проблемы с этими символами : # и всем остальным, что может разделить INVOICE и #. * 1009.*

Цифры просты.Все, что мне нужно, это (\d+) как мне получить первую часть?Я знаю, что мне нужно это (\w+), но тогда не-словесные символы выбивают меняМогу ли я получить толчок в правильном направлении, пожалуйста?

Ответы [ 3 ]

1 голос
/ 27 сентября 2019

Вы можете использовать \D для сопоставления без цифр.Захватите и слово, и не цифры в первой группе и цифры во второй группе, затем удалите пробелы в первой группе захвата.Вот пример того, как это может выглядеть:

text.scan(/(\w+\D+)(\d+)/).each { |group_1,| group_1.delete!(' ') }
#=> [["INVOICE#", "2599"], ["INVOICE", "0185570"], ["INVOICE:", "1739"], ["INVOICE-", "45441"], ["INVOICE:#", "1234"], ["INVOICE:#", "5678"]]

Вы также можете использовать gsub! или tr! вместо delete!.Замена \D на \W (не состоящий из слов) также будет работать.

Имейте в виду, что \w равно [A-Za-z0-9_] и может также соответствовать цифрам и подчеркиванию.

1 голос
/ 27 сентября 2019

Это может решить проблему: delete(' ').scan(/\d+|\D+/)

lines = ['INVOICE # 2599', 'INVOICE 0185570', 'INVOICE: 1739', 'INVOICE- 45441', 'INVOICE:# 1234', 'INVOICE :# 5678']
lines.map{ |line| line.delete(' ').scan(/\d+|\D+/) }

вывод:

[
    [0] [
        [0] "INVOICE#",
        [1] "2599"
    ],
    [1] [
        [0] "INVOICE",
        [1] "0185570"
    ],
    [2] [
        [0] "INVOICE:",
        [1] "1739"
    ],
    [3] [
        [0] "INVOICE-",
        [1] "45441"
    ],
    [4] [
        [0] "INVOICE:#",
        [1] "1234"
    ],
    [5] [
        [0] "INVOICE:#",
        [1] "5678"
    ]
]
0 голосов
/ 27 сентября 2019
text =<<~END
INVOICE # 2599
INVOICE 0185570
INVOICE: 1739
INVOICE- 45441
INVOICE:# 1234
INVOICE :# 5678
END

text.each_line.map { |s| s.gsub(/\s+(?!\d)/,'').split }
  #=> [["INVOICE#", "2599"], ["INVOICE", "0185570"], ["INVOICE:", "1739"],
  #    ["INVOICE-", "45441"], ["INVOICE:#", "1234"], ["INVOICE:#", "5678"]]  

Регулярное выражение, используемое gsub, гласит: «соответствует одному или нескольким пробелам, за которыми не следует цифра», (?!\d) означает негативный взгляд .Это немного отличается от s.gsub(/\s+(?=\D)/,''), «соответствует одному или нескольким пробелам, за которыми следует нецифровка», так как первый удаляет символ новой строки в конце каждой строки, а последний - нет.

Шагиследующим образом:

enum1 = text.each_line
  #=> #<Enumerator: "INVOICE # 2599\nINVOICE 0185570\nINVOICE: 1739\n
  #     INVOICE- 45441\nINVOICE:# 1234\nINVOICE :#5678\n":each_line>

Я использовал String#each_line вместо String#lines (или другие способы создания массива строк), чтобы избежать создания временного массива.

enum2 = enum1.map
  #=> #<Enumerator: #<Enumerator: "INVOICE # 2599\nINVOICE 0185570\nINVOICE: 1739\n
  #     INVOICE- 45441\nINVOICE:# 1234\nINVOICE :# 5678\n":each_line>:map> 

s = enum2.next
  #=> "INVOICE # 2599\n" 
t = s.gsub(/\s+(?!\d)/,'')
  #=> "INVOICE# 2599" 
t.split 
  #=> ["INVOICE#", "2599"] 

s = enum2.next
  #=> "INVOICE 0185570\n" 
t = s.gsub(/\s+(?!\d)/,'')
  #=> "INVOICE 0185570" 
t.split 
  #=> ["INVOICE", "0185570"] 

и т. Д.

Еще один способ сделать это - удалить пробелы, за которыми не следует цифра, прежде чем строка будет разбита на строки:

text.gsub(/\s+(?!\d)/, '').each_line.map(&:split)
 #=> [["INVOICE#", "2599"], ["INVOICE", "0185570"], ["INVOICE:", "1739"],
 #    ["INVOICE-", "45441"], ["INVOICE:#", "1234"], ["INVOICE:#", "5678"]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...