Улучшение моего регулярного выражения, чтобы включить числа, которые содержат десятичные дроби и знаки процента - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть следующее регулярное выражение, которое захватит первые N слов и завершится в следующий период, восклицательный знак или вопросительный знак.Мне нужно получить куски текстов, которые различаются по количеству слов, но я хочу полные предложения.

regex = (?:\w+[.?!]?\s+){10}(?:\w+,?\s+)*?\w+[.?!]

Работает со следующим текстом:

Терапия экстракт соломы и хитозанаИз одной только раковины креветок на 2, 4, 6, 8 и 10% обнаружено, что экстракт соломы 8% высокоэффективен в подавлении роста водорослей Microcystis spp.Количество клеток и количество хлорофилла а были уменьшены во время лечения.Оба значения непрерывно снижались до конца испытания.

https://regex101.com/r/ardIQ7/5

Однако это не будет работать со следующим текстом:

ТерапияИзвлечение соломы и хитозана из одних только раковин креветок составило 2, 4, 6, 8 и 10%. Обнаружено, что экстракт соломы 8,2% очень эффективен в подавлении роста водорослей Microcystis spp.Количество клеток и количество хлорофилла а были уменьшены во время лечения.Оба значения непрерывно снижались до конца испытания.

Это связано с цифрами (8,2%) с десятичными знаками и%.

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

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018
r = /
    (?:           # begin a non-capture group
      (?:           # begin a non-capture group
        \p{Alpha}+  # match one or more letters
      |           # or
        \-?       # optionally match a minus sign
        (?:       # begin non-capture group
          \d+     # match one or more digits
        |         # or
          \d+     # match one or more digits
          \.      # match a decimal point
          \d+     # match one or more digits
        )         # end non-capture group
        %?        # optionally match a percentage character
      )           # end non-capture group
      [,;:.!?]?   # optionally ('?' following ']') match a punctuation char
      [ ]+        # match one or more spaces      
    )             # end non-capture group
    {9,}?         # execute the preceding non-capture group at least 14 times, lazily ('?')
    (?:           # begin a non-capture group
      \p{Alpha}+  # match one or more letters
      |           # or
      \-?         # optionally match a minus sign
        (?:       # begin non-capture group
          \d+     # match one or more digits
        |         # or
          \d+     # match one or more digits
          \.      # match a decimal point
          \d+     # match one or more digits
        )         # end non-capture group
      %?          # optionally match a percentage character
    )             # end non-capture group  
    [.!?]         # match one of the three punctuation characters
    (?!\S)        # negative look-ahead: do not match a non-whitespace char
    /x            # free-spacing regex definition mode

Пусть text соответствует параграфу, который вы хотите изучить («Терапия извлекает солому ... конец испытания»).

Тогда

text[r]
  #=> "Therapy extract straw and chitosan from...the growth of algae Microcystis spp."

Мы можемупростить построение регулярного выражения (и избежать дублирования битов) следующим образом.

def construct_regex(min_nbr_words)
  common_bits = /(?:\p{Alpha}+|\-?(?:\d+|\d+\.\d+)%?)/
  /(?:#{common_bits}[,;:.!?]? +){#{min_nbr_words},}?#{common_bits}[.!?](?!\S)/
end

r = construct_regex(10)
  #=> /(?:(?-mix:\p{Alpha}+|\-?(?:\d+|\d+\.\d+)%?)[,;:.!?]? +){10,}?(?-mix:\p{Alpha}+|\-?(?:\d+|\d+\.\d+)%?)[.!?](?!\S)/

Это регулярное выражение можно было бы упростить, если бы было разрешено сопоставлять бессмысленные слова, такие как "ab2.3e%" или "2.3.2%".Как определено в настоящее время, регулярное выражение не будет соответствовать таким словам.

0 голосов
/ 20 сентября 2018

Попробуйте, (?:\S+[,.?!]?\s+){1,200}[\s\S]*?(\. |!|\?)

Это будет соответствовать количеству символов N.

Если N-й символ не заканчивал предложение, он будет совпадать до предыдущего предложения.N следует упомянуть как {1, N}

Regex

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...