pragmatic_segmenter 0.3.6 → 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f8c68d5563d388488aeacf96083dc2c81191b364
4
- data.tar.gz: 60f67ff5dc22c136f389f48ff9ba76350de013df
3
+ metadata.gz: e52784b9c640f8e05b250ef0382117952e385b38
4
+ data.tar.gz: b7ab33db4cb7c9e0b9b2d34a88e79a7a0f31f22d
5
5
  SHA512:
6
- metadata.gz: 3dcc1aa9da843232653928fb1a961f1b9d053aa9556924c4bed109a4c250c32bf1f11ccd69bdef6e6e1f40e3293e14d6274b06bd689cd03fb50c155200f29a98
7
- data.tar.gz: 5b0220d3d9645a78025bdd76b9bff39611255de9e8d568beb053d738e42152ada640bd3d973e6f833ef77e5ff66f12ecd7dd1450617062f7d37fb558ff25ad28
6
+ metadata.gz: e2de3bd5dc14e04c4cdac85c0eee27912c74ffe0f7d3b098c2e82861a3d4c247d7ed48c3c84a6d850151acce4da324fa2c997be896890ec6bcd342b7f5c682f0
7
+ data.tar.gz: d2630ec99ffe38b08eadb619c75f8c9622bc79a20abb0987de36f8fd04f3bac7e58a90835891ff4e5db9cec7f8e29d7c1fba3ba8bf91386b7086263a3b3cbd52
data/README.md CHANGED
@@ -828,6 +828,9 @@ To test the relative performance of different segmentation tools and libraries I
828
828
  **Version 0.3.6**
829
829
  * Refactor SENTENCE_STARTERS to each individual language and add SENTENCE_STARTERS for German
830
830
 
831
+ **Version 0.3.7**
832
+ * Add `unicode` gem and use it for downcasing to better handle cyrillic languages
833
+
831
834
  ## Contributing
832
835
 
833
836
  If you find a text that is incorrectly segmented using this gem, please submit an issue.
@@ -1,4 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
+ require 'unicode'
2
3
 
3
4
  module PragmaticSegmenter
4
5
  # This class searches for periods within an abbreviation and
@@ -26,7 +27,7 @@ module PragmaticSegmenter
26
27
 
27
28
  def search_for_abbreviations_in_string(txt)
28
29
  original = txt.dup
29
- downcased = txt.downcase
30
+ downcased = Unicode::downcase(txt)
30
31
  @language::Abbreviation::ABBREVIATIONS.each do |a|
31
32
  next unless downcased.include?(a.strip)
32
33
  abbrev_match = original.scan(/(?:^|\s|\r|\n)#{Regexp.escape(a.strip)}/i)
@@ -45,10 +46,10 @@ module PragmaticSegmenter
45
46
  prepositive = @language::Abbreviation::PREPOSITIVE_ABBREVIATIONS
46
47
  number_abbr = @language::Abbreviation::NUMBER_ABBREVIATIONS
47
48
  upper = /[[:upper:]]/.match(character.to_s)
48
- if upper.nil? || prepositive.include?(am.downcase.strip)
49
- if prepositive.include?(am.downcase.strip)
49
+ if upper.nil? || prepositive.include?(Unicode::downcase(am.strip))
50
+ if prepositive.include?(Unicode::downcase(am.strip))
50
51
  txt = replace_prepositive_abbr(txt, am)
51
- elsif number_abbr.include?(am.downcase.strip)
52
+ elsif number_abbr.include?(Unicode::downcase(am.strip))
52
53
  txt = replace_pre_number_abbr(txt, am)
53
54
  else
54
55
  txt = replace_period_of_abbr(txt, am)
@@ -22,11 +22,13 @@ require 'pragmatic_segmenter/languages/japanese'
22
22
  require 'pragmatic_segmenter/languages/dutch'
23
23
  require 'pragmatic_segmenter/languages/polish'
24
24
  require 'pragmatic_segmenter/languages/chinese'
25
+ require 'pragmatic_segmenter/languages/bulgarian'
25
26
 
26
27
  module PragmaticSegmenter
27
28
  module Languages
28
29
  LANGUAGE_CODES = {
29
30
  'en' => English,
31
+ 'bg' => Bulgarian,
30
32
  'de' => Deutsch,
31
33
  'es' => Spanish,
32
34
  'fr' => French,
@@ -0,0 +1,23 @@
1
+ module PragmaticSegmenter
2
+ module Languages
3
+ module Bulgarian
4
+ include Languages::Common
5
+
6
+ module Abbreviation
7
+ ABBREVIATIONS = ["p.s", "акад", "ал", "б.р", "б.ред", "бел.а", "бел.пр", "бр", "бул", "в", "вж", "вкл", "вм", "вр", "г", "ген", "гр", "дж", "дм", "доц", "др", "ем", "заб", "зам", "инж", "к.с", "кв", "кв.м", "кг", "км", "кор", "куб", "куб.м", "л", "лв", "м", "м.г", "мин", "млн", "млрд", "мм", "н.с", "напр", "пл", "полк", "проф", "р", "рис", "с", "св", "сек", "см", "сп", "срв", "ст", "стр", "т", "т.г", "т.е", "т.н", "т.нар", "табл", "тел", "у", "ул", "фиг", "ха", "хил", "ч", "чл", "щ.д"]
8
+ NUMBER_ABBREVIATIONS = []
9
+ PREPOSITIVE_ABBREVIATIONS = []
10
+ end
11
+
12
+ class AbbreviationReplacer < AbbreviationReplacer
13
+ SENTENCE_STARTERS = [].freeze
14
+
15
+ private
16
+ def replace_period_of_abbr(txt, abbr)
17
+ txt.gsub!(/(?<=\s#{abbr.strip})\.|(?<=^#{abbr.strip})\./, '∯')
18
+ txt
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -4,7 +4,7 @@ module PragmaticSegmenter
4
4
  include Languages::Common
5
5
 
6
6
  module Abbreviation
7
- ABBREVIATIONS = ['а', 'авт', 'адм.-терр', 'акад', 'в', 'вв', 'вкз', 'вост.-европ', 'г', 'гг', 'гос', 'гр', 'д', 'деп', 'дисс', 'дол', 'долл', 'ежедн', 'ж', 'жен', 'з', 'зап', 'зап.-европ', 'заруб', 'и', 'И', 'и', 'ин', 'иностр', 'инст', 'к', 'кв', 'К', 'Кв', 'куб', 'канд', 'кг', 'л', 'м', 'мин', 'моск', 'муж', 'нед', 'о', 'о', 'О', 'о', 'п', 'пер', 'пп', 'пр', 'просп', 'р', 'руб', 'с', 'сек', 'см', 'СПб', 'стр', 'т', 'т', 'тел', 'тов', 'тт', 'тыс', 'ул', 'у.е', 'y.e', 'у', 'y', 'Ф', 'ф', 'ч', 'пгт', 'проф', 'л.h', 'Л.Н', 'Н']
7
+ ABBREVIATIONS = ["y", "y.e", "а", "авт", "адм.-терр", "акад", "в", "вв", "вкз", "вост.-европ", "г", "гг", "гос", "гр", "д", "деп", "дисс", "дол", "долл", "ежедн", "ж", "жен", "з", "зап", "зап.-европ", "заруб", "и", "ин", "иностр", "инст", "к", "канд", "кв", "кг", "куб", "л", "л.h", "л.н", "м", "мин", "моск", "муж", "н", "нед", "о", "п", "пгт", "пер", "пп", "пр", "просп", "проф", "р", "руб", "с", "сек", "см", "спб", "стр", "т", "тел", "тов", "тт", "тыс", "у", "у.е", "ул", "ф", "ч"]
8
8
  PREPOSITIVE_ABBREVIATIONS = []
9
9
  NUMBER_ABBREVIATIONS = []
10
10
  end
@@ -149,9 +149,9 @@ module PragmaticSegmenter
149
149
  def replace_alphabet_list_parens(a)
150
150
  @text.gsub!(EXTRACT_ALPHABETICAL_LIST_LETTERS_REGEX).with_index do |m|
151
151
  if m.include?('(')
152
- a.eql?(m.dup.downcase.gsub!(/\(/, '')) ? "\r&✂&#{Regexp.escape(m.gsub!(/\(/, ''))}" : "#{m}"
152
+ a.eql?(Unicode::downcase(m.dup).gsub!(/\(/, '')) ? "\r&✂&#{Regexp.escape(m.gsub!(/\(/, ''))}" : "#{m}"
153
153
  else
154
- a.eql?(m.dup.downcase) ? "\r#{Regexp.escape(m)}" : "#{m}"
154
+ a.eql?(Unicode::downcase(m.dup)) ? "\r#{Regexp.escape(m)}" : "#{m}"
155
155
  end
156
156
  end
157
157
  end
@@ -183,7 +183,7 @@ module PragmaticSegmenter
183
183
  end
184
184
 
185
185
  def iterate_alphabet_array(regex, parens: false, roman_numeral: false)
186
- list_array = @text.scan(regex).map(&:downcase)
186
+ list_array = @text.scan(regex).map { |s| Unicode::downcase(s) }
187
187
  if roman_numeral
188
188
  alphabet = ROMAN_NUMERALS
189
189
  else
@@ -1,3 +1,3 @@
1
1
  module PragmaticSegmenter
2
- VERSION = "0.3.6"
2
+ VERSION = "0.3.7"
3
3
  end
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_runtime_dependency "unicode"
21
22
  spec.add_development_dependency "bundler", "~> 1.7"
22
23
  spec.add_development_dependency "rake", "~> 10.0"
23
24
  spec.add_development_dependency "rspec"
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe PragmaticSegmenter::Languages::Bulgarian, '(bg)' do
4
+
5
+ describe '#segment' do
6
+
7
+ it 'correctly segments text #001' do
8
+ ps = PragmaticSegmenter::Segmenter.new(text: "В първата половина на ноември т.г. ще бъде свикан Консултативният съвет за национална сигурност, обяви държавният глава.", language: 'bg')
9
+ expect(ps.segment).to eq(["В първата половина на ноември т.г. ще бъде свикан Консултативният съвет за национална сигурност, обяви държавният глава."])
10
+ end
11
+
12
+ it 'correctly segments text #002' do
13
+ ps = PragmaticSegmenter::Segmenter.new(text: "Компютърът е устройство с общо предназначение, което може да бъде програмирано да извършва набор от аритметични и/или логически операции. Възможността поредицата такива операции да бъде променяна позволява компютърът да се използва за решаването на теоретично всяка изчислителна/логическа задача. Обикновено целта на тези операции е обработката на въведена информация (данни), представена в цифров (дигитален) вид, резултатът от които може да се изведе в най-общо казано използваема форма.", language: 'bg')
14
+ expect(ps.segment).to eq(["Компютърът е устройство с общо предназначение, което може да бъде програмирано да извършва набор от аритметични и/или логически операции.", "Възможността поредицата такива операции да бъде променяна позволява компютърът да се използва за решаването на теоретично всяка изчислителна/логическа задача.", "Обикновено целта на тези операции е обработката на въведена информация (данни), представена в цифров (дигитален) вид, резултатът от които може да се изведе в най-общо казано използваема форма."])
15
+ end
16
+
17
+ it 'correctly segments text #003' do
18
+ ps = PragmaticSegmenter::Segmenter.new(text: "Пл. \"20 Април\"", language: 'bg')
19
+ expect(ps.segment).to eq(["Пл. \"20 Април\""])
20
+ end
21
+
22
+ it 'correctly segments text #004' do
23
+ ps = PragmaticSegmenter::Segmenter.new(text: "Той поставя началото на могъща династия, която управлява в продължение на 150 г. Саргон надделява в двубой с владетеля на град Ур и разширява териториите на държавата си по долното течение на Тигър и Ефрат. Стойностни, вкл. български и руски", language: 'bg')
24
+ expect(ps.segment).to eq(["Той поставя началото на могъща династия, която управлява в продължение на 150 г. Саргон надделява в двубой с владетеля на град Ур и разширява териториите на държавата си по долното течение на Тигър и Ефрат.", "Стойностни, вкл. български и руски"])
25
+ end
26
+ end
27
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pragmatic_segmenter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin S. Dias
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-05 00:00:00.000000000 Z
11
+ date: 2016-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: unicode
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -93,6 +107,7 @@ files:
93
107
  - lib/pragmatic_segmenter/languages/amharic.rb
94
108
  - lib/pragmatic_segmenter/languages/arabic.rb
95
109
  - lib/pragmatic_segmenter/languages/armenian.rb
110
+ - lib/pragmatic_segmenter/languages/bulgarian.rb
96
111
  - lib/pragmatic_segmenter/languages/burmese.rb
97
112
  - lib/pragmatic_segmenter/languages/chinese.rb
98
113
  - lib/pragmatic_segmenter/languages/common.rb
@@ -122,6 +137,7 @@ files:
122
137
  - spec/pragmatic_segmenter/languages/amharic_spec.rb
123
138
  - spec/pragmatic_segmenter/languages/arabic_spec.rb
124
139
  - spec/pragmatic_segmenter/languages/armenian_spec.rb
140
+ - spec/pragmatic_segmenter/languages/bulgarian_spec.rb
125
141
  - spec/pragmatic_segmenter/languages/burmese_spec.rb
126
142
  - spec/pragmatic_segmenter/languages/chinese_spec.rb
127
143
  - spec/pragmatic_segmenter/languages/deutsch_spec.rb
@@ -170,6 +186,7 @@ test_files:
170
186
  - spec/pragmatic_segmenter/languages/amharic_spec.rb
171
187
  - spec/pragmatic_segmenter/languages/arabic_spec.rb
172
188
  - spec/pragmatic_segmenter/languages/armenian_spec.rb
189
+ - spec/pragmatic_segmenter/languages/bulgarian_spec.rb
173
190
  - spec/pragmatic_segmenter/languages/burmese_spec.rb
174
191
  - spec/pragmatic_segmenter/languages/chinese_spec.rb
175
192
  - spec/pragmatic_segmenter/languages/deutsch_spec.rb