pragmatic_segmenter 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/lib/pragmatic_segmenter/abbreviation_replacer.rb +6 -6
  4. data/lib/pragmatic_segmenter/between_punctuation.rb +6 -4
  5. data/lib/pragmatic_segmenter/cleaner.rb +51 -47
  6. data/lib/pragmatic_segmenter/cleaner/rules.rb +86 -0
  7. data/lib/pragmatic_segmenter/languages.rb +21 -30
  8. data/lib/pragmatic_segmenter/languages/arabic.rb +0 -13
  9. data/lib/pragmatic_segmenter/languages/common.rb +67 -44
  10. data/lib/pragmatic_segmenter/languages/common/ellipsis.rb +37 -0
  11. data/lib/pragmatic_segmenter/languages/common/numbers.rb +90 -0
  12. data/lib/pragmatic_segmenter/languages/deutsch.rb +25 -48
  13. data/lib/pragmatic_segmenter/languages/english.rb +3 -3
  14. data/lib/pragmatic_segmenter/languages/japanese.rb +5 -13
  15. data/lib/pragmatic_segmenter/languages/persian.rb +0 -14
  16. data/lib/pragmatic_segmenter/languages/russian.rb +0 -25
  17. data/lib/pragmatic_segmenter/languages/spanish.rb +0 -9
  18. data/lib/pragmatic_segmenter/list.rb +60 -58
  19. data/lib/pragmatic_segmenter/{process.rb → processor.rb} +47 -26
  20. data/lib/pragmatic_segmenter/punctuation_replacer.rb +41 -20
  21. data/lib/pragmatic_segmenter/segmenter.rb +19 -5
  22. data/lib/pragmatic_segmenter/version.rb +1 -1
  23. data/pragmatic_segmenter.gemspec +1 -0
  24. data/spec/pragmatic_segmenter/languages/amharic_spec.rb +18 -0
  25. data/spec/pragmatic_segmenter/languages/arabic_spec.rb +59 -0
  26. data/spec/pragmatic_segmenter/languages/armenian_spec.rb +160 -0
  27. data/spec/pragmatic_segmenter/languages/burmese_spec.rb +18 -0
  28. data/spec/pragmatic_segmenter/languages/chinese_spec.rb +11 -0
  29. data/spec/pragmatic_segmenter/languages/deutsch_spec.rb +189 -0
  30. data/spec/pragmatic_segmenter/languages/dutch_spec.rb +23 -0
  31. data/spec/pragmatic_segmenter/languages/english_spec.rb +1348 -0
  32. data/spec/pragmatic_segmenter/languages/french_spec.rb +31 -0
  33. data/spec/pragmatic_segmenter/languages/greek_spec.rb +18 -0
  34. data/spec/pragmatic_segmenter/languages/hindi_spec.rb +18 -0
  35. data/spec/pragmatic_segmenter/languages/italian_spec.rb +190 -0
  36. data/spec/pragmatic_segmenter/languages/japanese_spec.rb +53 -0
  37. data/spec/pragmatic_segmenter/languages/persian_spec.rb +18 -0
  38. data/spec/pragmatic_segmenter/languages/polish_spec.rb +11 -0
  39. data/spec/pragmatic_segmenter/languages/russian_spec.rb +219 -0
  40. data/spec/pragmatic_segmenter/languages/spanish_spec.rb +189 -0
  41. data/spec/pragmatic_segmenter/languages/urdu_spec.rb +18 -0
  42. data/spec/pragmatic_segmenter/languages_spec.rb +31 -0
  43. data/spec/pragmatic_segmenter_spec.rb +24 -2583
  44. metadata +59 -8
  45. data/lib/pragmatic_segmenter/number.rb +0 -35
  46. data/lib/pragmatic_segmenter/rules.rb +0 -168
  47. data/lib/pragmatic_segmenter/rules/ellipsis.rb +0 -35
  48. data/lib/pragmatic_segmenter/rules/html.rb +0 -13
@@ -1,36 +1,35 @@
1
1
  # -*- encoding : utf-8 -*-
2
+ require 'pragmatic_segmenter/punctuation_replacer'
3
+ require 'pragmatic_segmenter/between_punctuation'
4
+
5
+
2
6
  require 'pragmatic_segmenter/list'
3
7
  require 'pragmatic_segmenter/abbreviation_replacer'
4
- require 'pragmatic_segmenter/number'
5
- require 'pragmatic_segmenter/rules/ellipsis'
6
8
  require 'pragmatic_segmenter/exclamation_words'
7
- require 'pragmatic_segmenter/punctuation_replacer'
8
- require 'pragmatic_segmenter/between_punctuation'
9
9
 
10
10
  module PragmaticSegmenter
11
11
  # This class processing segmenting the text.
12
- class Process
12
+ class Processor
13
13
 
14
14
  attr_reader :text
15
- def initialize(text:, language: Languages::Common)
16
- @text = text
15
+ def initialize(language: Languages::Common)
17
16
  @language = language
18
17
  end
19
18
 
20
- def process
21
- reformatted_text = List.new(text: text).add_line_break
22
- reformatted_text = replace_abbreviations(reformatted_text)
23
- reformatted_text = replace_numbers(reformatted_text)
24
- reformatted_text = replace_continuous_punctuation(reformatted_text)
25
- reformatted_text.apply(@language::AbbreviationsWithMultiplePeriodsAndEmailRule)
26
- reformatted_text.apply(@language::GeoLocationRule)
27
- split_into_segments(reformatted_text)
19
+ def process(text:)
20
+ @text = List.new(text: text).add_line_break
21
+ replace_abbreviations
22
+ replace_numbers
23
+ replace_continuous_punctuation
24
+ @text.apply(@language::Abbreviations::WithMultiplePeriodsAndEmailRule)
25
+ @text.apply(@language::GeoLocationRule)
26
+ split_into_segments
28
27
  end
29
28
 
30
29
  private
31
30
 
32
- def split_into_segments(txt)
33
- check_for_parens_between_quotes(txt).split("\r")
31
+ def split_into_segments
32
+ check_for_parens_between_quotes(@text).split("\r")
34
33
  .map! { |segment| segment.apply(@language::SingleNewLineRule, @language::EllipsisRules::All) }
35
34
  .map { |segment| check_for_punctuation(segment) }.flatten
36
35
  .map! { |segment| segment.apply(@language::SubSymbolsRules::All) }
@@ -41,7 +40,11 @@ module PragmaticSegmenter
41
40
 
42
41
  def post_process_segments(txt)
43
42
  return if consecutive_underscore?(txt) || txt.length < 2
44
- txt.apply(@language::ReinsertEllipsisRules::All).apply(@language::ExtraWhiteSpaceRule)
43
+ txt.apply(
44
+ @language::ReinsertEllipsisRules::All,
45
+ @language::ExtraWhiteSpaceRule
46
+ )
47
+
45
48
  if txt =~ @language::QUOTATION_AT_END_OF_SENTENCE_REGEX
46
49
  txt.split(@language::SPLIT_SPACE_QUOTATION_AT_END_OF_SENTENCE_REGEX)
47
50
  else
@@ -56,9 +59,8 @@ module PragmaticSegmenter
56
59
  end
57
60
  end
58
61
 
59
- def replace_continuous_punctuation(txt)
60
- return txt unless txt =~ @language::CONTINUOUS_PUNCTUATION_REGEX
61
- txt.gsub!(@language::CONTINUOUS_PUNCTUATION_REGEX) do |match|
62
+ def replace_continuous_punctuation
63
+ @text.gsub!(@language::CONTINUOUS_PUNCTUATION_REGEX) do |match|
62
64
  match.gsub(/!/, '&ᓴ&').gsub(/\?/, '&ᓷ&')
63
65
  end
64
66
  end
@@ -89,19 +91,38 @@ module PragmaticSegmenter
89
91
  sentence_boundary_punctuation(txt)
90
92
  end
91
93
 
92
- def replace_numbers(txt)
93
- Number.new(text: txt).replace
94
+ def replace_numbers
95
+ @text.apply @language::Numbers::All
94
96
  end
95
97
 
96
- def replace_abbreviations(txt)
97
- AbbreviationReplacer.new(text: txt, language: @language).replace
98
+ def abbreviations_replacer
99
+ if defined? @language::AbbreviationReplacer
100
+ @language::AbbreviationReplacer
101
+ else
102
+ AbbreviationReplacer
103
+ end
104
+ end
105
+
106
+ def replace_abbreviations
107
+ @text = abbreviations_replacer.new(text: @text, language: @language).replace
108
+ end
109
+
110
+ def between_punctuation_processor
111
+ if defined? @language::BetweenPunctuation
112
+ @language::BetweenPunctuation
113
+ else
114
+ BetweenPunctuation
115
+ end
98
116
  end
99
117
 
100
118
  def between_punctuation(txt)
101
- BetweenPunctuation.new(text: txt).replace
119
+ between_punctuation_processor.new(text: txt).replace
102
120
  end
103
121
 
104
122
  def sentence_boundary_punctuation(txt)
123
+ txt = txt.apply @language::ReplaceColonBetweenNumbersRule if defined? @language::ReplaceColonBetweenNumbersRule
124
+ txt = txt.apply @language::ReplaceNonSentenceBoundaryCommaRule if defined? @language::ReplaceNonSentenceBoundaryCommaRule
125
+
105
126
  txt.scan(@language::SENTENCE_BOUNDARY_REGEX)
106
127
  end
107
128
  end
@@ -4,45 +4,66 @@ module PragmaticSegmenter
4
4
  # This class replaces punctuation that is typically a sentence boundary
5
5
  # but in this case is not a sentence boundary.
6
6
  class PunctuationReplacer
7
- # Rubular: http://rubular.com/r/2YFrKWQUYi
8
- BETWEEN_SINGLE_QUOTES_REGEX = /(?<=\s)'(?:[^']|'[a-zA-Z])*'/
7
+ module Rules
8
+ module EscapeRegexReservedCharacters
9
+ LeftParen = Rule.new('(', '\\(')
10
+ RightParen = Rule.new(')', '\\)')
11
+ LeftBracket = Rule.new('[', '\\[')
12
+ RightBracket = Rule.new(']', '\\]')
13
+ Dash = Rule.new('-', '\\-')
14
+
15
+ All = [ LeftParen, RightParen,
16
+ LeftBracket, RightBracket, Dash ]
17
+ end
18
+
19
+ module SubEscapedRegexReservedCharacters
20
+ SubLeftParen = Rule.new('\\(', '(')
21
+ SubRightParen = Rule.new('\\)', ')')
22
+ SubLeftBracket = Rule.new('\\[', '[')
23
+ SubRightBracket = Rule.new('\\]', ']')
24
+ SubDash = Rule.new('\\-', '-')
25
+
26
+ All = [ SubLeftParen, SubRightParen,
27
+ SubLeftBracket, SubRightBracket, SubDash ]
28
+ end
29
+
30
+ end
9
31
 
10
- include Rules
11
32
  attr_reader :matches_array, :text, :match_type
12
- def initialize(text:, matches_array:, **args)
33
+ def initialize(text:, matches_array:, match_type: nil)
13
34
  @text = text
14
35
  @matches_array = matches_array
15
- @match_type = args[:match_type]
36
+ @match_type = match_type
16
37
  end
17
38
 
18
39
  def replace
19
- replace_punctuation(matches_array, text)
40
+ replace_punctuation(matches_array)
20
41
  end
21
42
 
22
43
  private
23
44
 
24
- def replace_punctuation(array, txt)
45
+ def replace_punctuation(array)
25
46
  return if !array || array.empty?
26
- txt.apply(EscapeRegexReservedCharacters::All)
47
+ @text.apply(Rules::EscapeRegexReservedCharacters::All)
27
48
  array.each do |a|
28
- a.apply(EscapeRegexReservedCharacters::All)
29
- sub = sub_characters(txt, a, '.', '∯')
30
- sub_1 = sub_characters(txt, sub, '。', '&ᓰ&')
31
- sub_2 = sub_characters(txt, sub_1, '.', '&ᓱ&')
32
- sub_3 = sub_characters(txt, sub_2, '!', '&ᓳ&')
33
- sub_4 = sub_characters(txt, sub_3, '!', '&ᓴ&')
34
- sub_5 = sub_characters(txt, sub_4, '?', '&ᓷ&')
35
- sub_6 = sub_characters(txt, sub_5, '?', '&ᓸ&')
49
+ a.apply(Rules::EscapeRegexReservedCharacters::All)
50
+ sub = sub_characters(a, '.', '∯')
51
+ sub_1 = sub_characters(sub, '。', '&ᓰ&')
52
+ sub_2 = sub_characters(sub_1, '.', '&ᓱ&')
53
+ sub_3 = sub_characters(sub_2, '!', '&ᓳ&')
54
+ sub_4 = sub_characters(sub_3, '!', '&ᓴ&')
55
+ sub_5 = sub_characters(sub_4, '?', '&ᓷ&')
56
+ sub_6 = sub_characters(sub_5, '?', '&ᓸ&')
36
57
  unless match_type.eql?('single')
37
- sub_7 = sub_characters(txt, sub_6, "'", '&⎋&')
58
+ sub_7 = sub_characters(sub_6, "'", '&⎋&')
38
59
  end
39
60
  end
40
- txt.apply(SubEscapedRegexReservedCharacters::All)
61
+ @text.apply(Rules::SubEscapedRegexReservedCharacters::All)
41
62
  end
42
63
 
43
- def sub_characters(txt, string, char_a, char_b)
64
+ def sub_characters(string, char_a, char_b)
44
65
  sub = string.gsub(char_a, char_b)
45
- txt.gsub!(/#{Regexp.escape(string)}/, "#{sub}")
66
+ @text.gsub!(/#{Regexp.escape(string)}/, "#{sub}")
46
67
  sub
47
68
  end
48
69
  end
@@ -4,16 +4,16 @@ require 'pragmatic_segmenter/languages'
4
4
  module PragmaticSegmenter
5
5
  # This class segments a text into an array of sentences.
6
6
  class Segmenter
7
- include Languages
8
7
  attr_reader :text, :language, :doc_type
9
8
 
10
- def initialize(text:, language: nil, doc_type: nil, clean: true)
9
+ def initialize(text:, language: 'en', doc_type: nil, clean: true)
11
10
  return unless text
12
- @language = language || 'en'
11
+ @language = language
12
+ @language_module = Languages.get_language_by_code(language)
13
13
  @doc_type = doc_type
14
14
 
15
15
  if clean
16
- @text = cleaner_class.new(text: text, doc_type: @doc_type).clean
16
+ @text = cleaner.new(text: text, doc_type: @doc_type, language: @language_module).clean
17
17
  else
18
18
  @text = text
19
19
  end
@@ -21,7 +21,21 @@ module PragmaticSegmenter
21
21
 
22
22
  def segment
23
23
  return [] unless @text
24
- process_class.new(text: @text, language: language_module).process
24
+ processor.new(language: @language_module).process(text: @text)
25
+ end
26
+
27
+ private
28
+
29
+ def processor
30
+ @language_module::Processor
31
+ rescue
32
+ Processor
33
+ end
34
+
35
+ def cleaner
36
+ @language_module::Cleaner
37
+ rescue
38
+ Cleaner
25
39
  end
26
40
  end
27
41
  end
@@ -1,3 +1,3 @@
1
1
  module PragmaticSegmenter
2
- VERSION = "0.3.3"
2
+ VERSION = "0.3.4"
3
3
  end
@@ -21,4 +21,5 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.7"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
  spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "guard-rspec"
24
25
  end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe PragmaticSegmenter::Languages::Amharic, '(am)' do
4
+
5
+ context "Golden Rules" do
6
+ it "Sentence ending punctuation #001" do
7
+ ps = PragmaticSegmenter::Segmenter.new(text: "እንደምን አለህ፧መልካም ቀን ይሁንልህ።እባክሽ ያልሽዉን ድገሚልኝ።", language: 'am')
8
+ expect(ps.segment).to eq(["እንደምን አለህ፧", "መልካም ቀን ይሁንልህ።", "እባክሽ ያልሽዉን ድገሚልኝ።"])
9
+ end
10
+ end
11
+
12
+ describe '#segment' do
13
+ it 'correctly segments text #001' do
14
+ ps = PragmaticSegmenter::Segmenter.new(text: "እንደምን አለህ፧መልካም ቀን ይሁንልህ።እባክሽ ያልሽዉን ድገሚልኝ።", language: 'am')
15
+ expect(ps.segment).to eq(["እንደምን አለህ፧", "መልካም ቀን ይሁንልህ።", "እባክሽ ያልሽዉን ድገሚልኝ።"])
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe PragmaticSegmenter::Languages::Arabic, '(ar)' do
4
+
5
+ context "Golden Rules" do
6
+ it "Regular punctuation #001" do
7
+ ps = PragmaticSegmenter::Segmenter.new(text: "سؤال وجواب: ماذا حدث بعد الانتخابات الايرانية؟ طرح الكثير من التساؤلات غداة ظهور نتائج الانتخابات الرئاسية الايرانية التي أججت مظاهرات واسعة واعمال عنف بين المحتجين على النتائج ورجال الامن. يقول معارضو الرئيس الإيراني إن الطريقة التي اعلنت بها النتائج كانت مثيرة للاستغراب.", language: "ar")
8
+ expect(ps.segment).to eq(["سؤال وجواب:", "ماذا حدث بعد الانتخابات الايرانية؟", "طرح الكثير من التساؤلات غداة ظهور نتائج الانتخابات الرئاسية الايرانية التي أججت مظاهرات واسعة واعمال عنف بين المحتجين على النتائج ورجال الامن.", "يقول معارضو الرئيس الإيراني إن الطريقة التي اعلنت بها النتائج كانت مثيرة للاستغراب."])
9
+ end
10
+
11
+ it "Abbreviations #002" do
12
+ ps = PragmaticSegmenter::Segmenter.new(text: "وقال د‪.‬ ديفيد ريدي و الأطباء الذين كانوا يعالجونها في مستشفى برمنجهام إنها كانت تعاني من أمراض أخرى. وليس معروفا ما اذا كانت قد توفيت بسبب اصابتها بأنفلونزا الخنازير.", language: "ar")
13
+ expect(ps.segment).to eq(["وقال د‪.‬ ديفيد ريدي و الأطباء الذين كانوا يعالجونها في مستشفى برمنجهام إنها كانت تعاني من أمراض أخرى.", "وليس معروفا ما اذا كانت قد توفيت بسبب اصابتها بأنفلونزا الخنازير."])
14
+ end
15
+
16
+ it "Numbers and Dates #003" do
17
+ ps = PragmaticSegmenter::Segmenter.new(text: "ومن المنتظر أن يكتمل مشروع خط أنابيب نابوكو البالغ طوله 3300 كليومترا في 12‪/‬08‪/‬2014 بتكلفة تُقدر بـ 7.9 مليارات يورو أي نحو 10.9 مليارات دولار. ومن المقرر أن تصل طاقة ضخ الغاز في المشروع 31 مليار متر مكعب انطلاقا من بحر قزوين مرورا بالنمسا وتركيا ودول البلقان دون المرور على الأراضي الروسية.", language: "ar")
18
+ expect(ps.segment).to eq(["ومن المنتظر أن يكتمل مشروع خط أنابيب نابوكو البالغ طوله 3300 كليومترا في 12‪/‬08‪/‬2014 بتكلفة تُقدر بـ 7.9 مليارات يورو أي نحو 10.9 مليارات دولار.", "ومن المقرر أن تصل طاقة ضخ الغاز في المشروع 31 مليار متر مكعب انطلاقا من بحر قزوين مرورا بالنمسا وتركيا ودول البلقان دون المرور على الأراضي الروسية."])
19
+ end
20
+
21
+ it "Time #004" do
22
+ ps = PragmaticSegmenter::Segmenter.new(text: "الاحد, 21 فبراير/ شباط, 2010, 05:01 GMT الصنداي تايمز: رئيس الموساد قد يصبح ضحية الحرب السرية التي شتنها بنفسه. العقل المنظم هو مئير داجان رئيس الموساد الإسرائيلي الذي يشتبه بقيامه باغتيال القائد الفلسطيني في حركة حماس محمود المبحوح في دبي.", language: "ar")
23
+ expect(ps.segment).to eq(["الاحد, 21 فبراير/ شباط, 2010, 05:01 GMT الصنداي تايمز:", "رئيس الموساد قد يصبح ضحية الحرب السرية التي شتنها بنفسه.", "العقل المنظم هو مئير داجان رئيس الموساد الإسرائيلي الذي يشتبه بقيامه باغتيال القائد الفلسطيني في حركة حماس محمود المبحوح في دبي."])
24
+ end
25
+
26
+ it "Comma #005" do
27
+ ps = PragmaticSegmenter::Segmenter.new(text: "عثر في الغرفة على بعض أدوية علاج ارتفاع ضغط الدم، والقلب، زرعها عملاء الموساد كما تقول مصادر إسرائيلية، وقرر الطبيب أن الفلسطيني قد توفي وفاة طبيعية ربما إثر نوبة قلبية، وبدأت مراسم الحداد عليه", language: "ar")
28
+ expect(ps.segment).to eq(["عثر في الغرفة على بعض أدوية علاج ارتفاع ضغط الدم، والقلب،", "زرعها عملاء الموساد كما تقول مصادر إسرائيلية،", "وقرر الطبيب أن الفلسطيني قد توفي وفاة طبيعية ربما إثر نوبة قلبية،", "وبدأت مراسم الحداد عليه"])
29
+ end
30
+ end
31
+
32
+ # Thanks to Mahmoud Holmez for the Arabic test examples.
33
+ describe '#segment' do
34
+ it 'correctly segments text #001' do
35
+ ps = PragmaticSegmenter::Segmenter.new(text: "سؤال وجواب: ماذا حدث بعد الانتخابات الايرانية؟ طرح الكثير من التساؤلات غداة ظهور نتائج الانتخابات الرئاسية الايرانية التي أججت مظاهرات واسعة واعمال عنف بين المحتجين على النتائج ورجال الامن. يقول معارضو الرئيس الإيراني إن الطريقة التي اعلنت بها النتائج كانت مثيرة للاستغراب.", language: 'ar')
36
+ expect(ps.segment).to eq(["سؤال وجواب:", "ماذا حدث بعد الانتخابات الايرانية؟", "طرح الكثير من التساؤلات غداة ظهور نتائج الانتخابات الرئاسية الايرانية التي أججت مظاهرات واسعة واعمال عنف بين المحتجين على النتائج ورجال الامن.", "يقول معارضو الرئيس الإيراني إن الطريقة التي اعلنت بها النتائج كانت مثيرة للاستغراب."])
37
+ end
38
+
39
+ it 'correctly segments text #002' do
40
+ ps = PragmaticSegmenter::Segmenter.new(text: "وقال د‪.‬ ديفيد ريدي و الأطباء الذين كانوا يعالجونها في مستشفى برمنجهام إنها كانت تعاني من أمراض أخرى. وليس معروفا ما اذا كانت قد توفيت بسبب اصابتها بأنفلونزا الخنازير.", language: 'ar')
41
+ expect(ps.segment).to eq(["وقال د‪.‬ ديفيد ريدي و الأطباء الذين كانوا يعالجونها في مستشفى برمنجهام إنها كانت تعاني من أمراض أخرى.", "وليس معروفا ما اذا كانت قد توفيت بسبب اصابتها بأنفلونزا الخنازير."])
42
+ end
43
+
44
+ it 'correctly segments text #003' do
45
+ ps = PragmaticSegmenter::Segmenter.new(text: "ومن المنتظر أن يكتمل مشروع خط أنابيب نابوكو البالغ طوله 3300 كليومترا في 12‪/‬08‪/‬2014 بتكلفة تُقدر بـ 7.9 مليارات يورو أي نحو 10.9 مليارات دولار. ومن المقرر أن تصل طاقة ضخ الغاز في المشروع 31 مليار متر مكعب انطلاقا من بحر قزوين مرورا بالنمسا وتركيا ودول البلقان دون المرور على الأراضي الروسية.", language: 'ar')
46
+ expect(ps.segment).to eq(["ومن المنتظر أن يكتمل مشروع خط أنابيب نابوكو البالغ طوله 3300 كليومترا في 12‪/‬08‪/‬2014 بتكلفة تُقدر بـ 7.9 مليارات يورو أي نحو 10.9 مليارات دولار.", "ومن المقرر أن تصل طاقة ضخ الغاز في المشروع 31 مليار متر مكعب انطلاقا من بحر قزوين مرورا بالنمسا وتركيا ودول البلقان دون المرور على الأراضي الروسية."])
47
+ end
48
+
49
+ it 'correctly segments text #004' do
50
+ ps = PragmaticSegmenter::Segmenter.new(text: "الاحد, 21 فبراير/ شباط, 2010, 05:01 GMT الصنداي تايمز: رئيس الموساد قد يصبح ضحية الحرب السرية التي شتنها بنفسه. العقل المنظم هو مئير داجان رئيس الموساد الإسرائيلي الذي يشتبه بقيامه باغتيال القائد الفلسطيني في حركة حماس محمود المبحوح في دبي.", language: 'ar')
51
+ expect(ps.segment).to eq(["الاحد, 21 فبراير/ شباط, 2010, 05:01 GMT الصنداي تايمز:", "رئيس الموساد قد يصبح ضحية الحرب السرية التي شتنها بنفسه.", "العقل المنظم هو مئير داجان رئيس الموساد الإسرائيلي الذي يشتبه بقيامه باغتيال القائد الفلسطيني في حركة حماس محمود المبحوح في دبي."])
52
+ end
53
+
54
+ it 'correctly segments text #005' do
55
+ ps = PragmaticSegmenter::Segmenter.new(text: "عثر في الغرفة على بعض أدوية علاج ارتفاع ضغط الدم، والقلب، زرعها عملاء الموساد كما تقول مصادر إسرائيلية، وقرر الطبيب أن الفلسطيني قد توفي وفاة طبيعية ربما إثر نوبة قلبية، وبدأت مراسم الحداد عليه", language: 'ar')
56
+ expect(ps.segment).to eq(["عثر في الغرفة على بعض أدوية علاج ارتفاع ضغط الدم، والقلب،", "زرعها عملاء الموساد كما تقول مصادر إسرائيلية،", "وقرر الطبيب أن الفلسطيني قد توفي وفاة طبيعية ربما إثر نوبة قلبية،", "وبدأت مراسم الحداد عليه"])
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,160 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe PragmaticSegmenter::Languages::Armenian, '(hy)' do
4
+
5
+ context "Golden Rules" do
6
+ it "Sentence ending punctuation #001" do
7
+ ps = PragmaticSegmenter::Segmenter.new(text: "Ի՞նչ ես մտածում: Ոչինչ:", language: "hy")
8
+ expect(ps.segment).to eq(["Ի՞նչ ես մտածում:", "Ոչինչ:"])
9
+ end
10
+
11
+ it "Ellipsis #002" do
12
+ ps = PragmaticSegmenter::Segmenter.new(text: "Ապրիլի 24-ին սկսեց անձրևել...Այդպես էի գիտեի:", language: "hy")
13
+ expect(ps.segment).to eq(["Ապրիլի 24-ին սկսեց անձրևել...Այդպես էի գիտեի:"])
14
+ end
15
+
16
+ it "Period is not a sentence boundary #003" do
17
+ ps = PragmaticSegmenter::Segmenter.new(text: "Այսպիսով` մոտենում ենք ավարտին: Տրամաբանությյունը հետևյալն է. պարզություն և աշխատանք:", language: "hy")
18
+ expect(ps.segment).to eq(["Այսպիսով` մոտենում ենք ավարտին:", "Տրամաբանությյունը հետևյալն է. պարզություն և աշխատանք:"])
19
+ end
20
+ end
21
+
22
+ describe '#segment' do
23
+ # Thanks to Armine Abelyan for the Armenian test examples.
24
+
25
+ it 'correctly segments text #001' do
26
+ ps = PragmaticSegmenter::Segmenter.new(text: "Սա այն փուլն է, երբ տեղի է ունենում Համակարգի մշակումը: Համաձայն Փուլ 2-ի, Մատակարարը մշակում և/կամ հարմարեցնում է համապատասխան ծրագիրը, տեղադրում ծրագրի բաղկացուցիչները, կատարում առանձին բլոկի և համակարգի թեստավորում և ներառում տարբեր մոդուլներ եզակի աշխատանքային համակարգում, որը կազմում է այս Փուլի արդյունքը:", language: 'hy')
27
+ expect(ps.segment).to eq(["Սա այն փուլն է, երբ տեղի է ունենում Համակարգի մշակումը:", "Համաձայն Փուլ 2-ի, Մատակարարը մշակում և/կամ հարմարեցնում է համապատասխան ծրագիրը, տեղադրում ծրագրի բաղկացուցիչները, կատարում առանձին բլոկի և համակարգի թեստավորում և ներառում տարբեր մոդուլներ եզակի աշխատանքային համակարգում, որը կազմում է այս Փուլի արդյունքը:"])
28
+ end
29
+
30
+ it 'correctly segments text #002' do
31
+ ps = PragmaticSegmenter::Segmenter.new(text: "Մատակարարի նախագծի անձնակազմի կողմից համակարգի թեստերը հաջող անցնելուց հետո, Համակարգը տրվում է Գնորդին թեստավորման համար: 2-րդ փուլում, հիմք ընդունելով թեստային սցենարիոները, թեստերը կատարվում են Կառավարության կողմից Մատակարարի աջակցությամբ: Այս թեստերի թիրախը հանդիսանում է Համակարգի` որպես մեկ ամբողջության և համակարգի գործունեության ստուգումը համաձայն տեխնիկական բնութագրերի: Այս թեստերի հաջողակ ավարտից հետո, Համակարգը ժամանակավոր ընդունվում է Կառավարության կողմից: Այս թեստերի արդյունքները փաստաթղթային ձևով կներակայացվեն Թեստային Արդյունքների Հաշվետվություններում: Մատակարարը պետք է տրամադրի հետևյալը`", language: 'hy')
32
+ expect(ps.segment).to eq(["Մատակարարի նախագծի անձնակազմի կողմից համակարգի թեստերը հաջող անցնելուց հետո, Համակարգը տրվում է Գնորդին թեստավորման համար:", "2-րդ փուլում, հիմք ընդունելով թեստային սցենարիոները, թեստերը կատարվում են Կառավարության կողմից Մատակարարի աջակցությամբ:", "Այս թեստերի թիրախը հանդիսանում է Համակարգի` որպես մեկ ամբողջության և համակարգի գործունեության ստուգումը համաձայն տեխնիկական բնութագրերի:", "Այս թեստերի հաջողակ ավարտից հետո, Համակարգը ժամանակավոր ընդունվում է Կառավարության կողմից:", "Այս թեստերի արդյունքները փաստաթղթային ձևով կներակայացվեն Թեստային Արդյունքների Հաշվետվություններում:", "Մատակարարը պետք է տրամադրի հետևյալը`"])
33
+ end
34
+
35
+ it 'correctly segments text #003' do
36
+ ps = PragmaticSegmenter::Segmenter.new(text: "Մատակարարի նախագծի անձնակազմի կողմից համակարգի թեստերը հաջող անցնելուց հետո, Համակարգը տրվում է Գնորդին թեստավորման համար: 2-րդ փուլում, հիմք ընդունելով թեստային սցենարիոները, թեստերը կատարվում են Կառավարության կողմից Մատակարարի աջակցությամբ: Այս թեստերի թիրախը հանդիսանում է Համակարգի` որպես մեկ ամբողջության և համակարգի գործունեության ստուգումը համաձայն տեխնիկական բնութագրերի: Այս թեստերի հաջողակ ավարտից հետո, Համակարգը ժամանակավոր ընդունվում է Կառավարության կողմից: Այս թեստերի արդյունքները փաստաթղթային ձևով կներակայացվեն Թեստային Արդյունքների Հաշվետվություններում: Մատակարարը պետք է տրամադրի հետևյալը`", language: 'hy')
37
+ expect(ps.segment).to eq(["Մատակարարի նախագծի անձնակազմի կողմից համակարգի թեստերը հաջող անցնելուց հետո, Համակարգը տրվում է Գնորդին թեստավորման համար:", "2-րդ փուլում, հիմք ընդունելով թեստային սցենարիոները, թեստերը կատարվում են Կառավարության կողմից Մատակարարի աջակցությամբ:", "Այս թեստերի թիրախը հանդիսանում է Համակարգի` որպես մեկ ամբողջության և համակարգի գործունեության ստուգումը համաձայն տեխնիկական բնութագրերի:", "Այս թեստերի հաջողակ ավարտից հետո, Համակարգը ժամանակավոր ընդունվում է Կառավարության կողմից:", "Այս թեստերի արդյունքները փաստաթղթային ձևով կներակայացվեն Թեստային Արդյունքների Հաշվետվություններում:", "Մատակարարը պետք է տրամադրի հետևյալը`"])
38
+ end
39
+
40
+ it 'correctly segments text #004' do
41
+ # "Hello world. My name is Armine." ==> ["Hello world.", "My name is Armine."]
42
+ ps = PragmaticSegmenter::Segmenter.new(text: "Բարև Ձեզ: Իմ անունն էԱրմինե:", language: 'hy')
43
+ expect(ps.segment).to eq(["Բարև Ձեզ:", "Իմ անունն էԱրմինե:"])
44
+ end
45
+
46
+ it 'correctly segments text #005' do
47
+ # "Today is Monday. I am going to work." ==> ["Today is Monday.", "I am going to work."]
48
+ ps = PragmaticSegmenter::Segmenter.new(text: "Այսօր երկուշաբթի է: Ես գնում եմ աշխատանքի:", language: 'hy')
49
+ expect(ps.segment).to eq(["Այսօր երկուշաբթի է:", "Ես գնում եմ աշխատանքի:"])
50
+ end
51
+
52
+ it 'correctly segments text #006' do
53
+ # "Tomorrow is September 1st. We are going to school." ==> ["Tomorrow is September 1st.", "We are going to school."]
54
+ ps = PragmaticSegmenter::Segmenter.new(text: "Վաղը սեպտեմբերի 1-ն է: Մենք գնում ենք դպրոց:", language: 'hy')
55
+ expect(ps.segment).to eq(["Վաղը սեպտեմբերի 1-ն է:", "Մենք գնում ենք դպրոց:"])
56
+ end
57
+
58
+ it 'correctly segments text #007' do
59
+ # "Yes, I understood. I really love you." ==> ["Yes, I understood.", "I really love you."]
60
+ ps = PragmaticSegmenter::Segmenter.new(text: "Այո, ես հասկացա: Ես իսկապես քեզ սիրում եմ:", language: 'hy')
61
+ expect(ps.segment).to eq(["Այո, ես հասկացա:", "Ես իսկապես քեզ սիրում եմ:"])
62
+ end
63
+
64
+ it 'correctly segments text #008' do
65
+ # "Close the windows. It is raining in the evening." ==> ["Close the windows.", "It is raining in the evening."]
66
+ ps = PragmaticSegmenter::Segmenter.new(text: "Փակիր պատուհանները: Երեկոյան անձրևում է:", language: 'hy')
67
+ expect(ps.segment).to eq(["Փակիր պատուհանները:", "Երեկոյան անձրևում է:"])
68
+ end
69
+
70
+ it 'correctly segments text #009' do
71
+ # "It is dark. I should go home." ==> ["It is dark.", "I should go home."]
72
+ ps = PragmaticSegmenter::Segmenter.new(text: "Մութ է: Ես պետք է տուն վերադառնամ:", language: 'hy')
73
+ expect(ps.segment).to eq(["Մութ է:", "Ես պետք է տուն վերադառնամ:"])
74
+ end
75
+
76
+ it 'correctly segments text #010' do
77
+ # "You know, I am starting to believe. Everything is changing." ==> ["You know, I am starting to believe.", "Everything is changing."]
78
+ ps = PragmaticSegmenter::Segmenter.new(text: "Գիտես, սկսել եմ հավատալ: Ամեն ինչ փոխվում է:", language: 'hy')
79
+ expect(ps.segment).to eq(["Գիտես, սկսել եմ հավատալ:", "Ամեն ինչ փոխվում է:"])
80
+ end
81
+
82
+ it 'correctly segments text #011' do
83
+ # "It is a new Christmas tree. We should decorate it." ==> ["It is a new Christmas tree.", "We should decorate it."]
84
+ ps = PragmaticSegmenter::Segmenter.new(text: "Տոնածառը նոր է: Պետք է այն զարդարել:", language: 'hy')
85
+ expect(ps.segment).to eq(["Տոնածառը նոր է:", "Պետք է այն զարդարել:"])
86
+ end
87
+
88
+ it 'correctly segments text #012' do
89
+ # "I am in hurry. I could not wait you." ==> ["I am in hurry.", "I could not wait you."]
90
+ ps = PragmaticSegmenter::Segmenter.new(text: "Ես շտապում եմ: Ես քեզ չեմ կարող սպասել:", language: 'hy')
91
+ expect(ps.segment).to eq(["Ես շտապում եմ:", "Ես քեզ չեմ կարող սպասել:"])
92
+ end
93
+
94
+ it 'correctly segments text #013' do
95
+ # "Wait, we love each other. I want us to live together." ==> ["Wait, we love each other.", "I want us to live together."]
96
+ ps = PragmaticSegmenter::Segmenter.new(text: "Սպասիր, մենք իրար սիրում ենք: Ցանկանում եմ միասին ապրենք:", language: 'hy')
97
+ expect(ps.segment).to eq(["Սպասիր, մենք իրար սիրում ենք:", "Ցանկանում եմ միասին ապրենք:"])
98
+ end
99
+
100
+ it 'correctly segments text #014' do
101
+ # "No, I do not think so. It is not true." ==> ["No, I do not think so.", "It is not true."]
102
+ ps = PragmaticSegmenter::Segmenter.new(text: "Ոչ, այդպես չեմ կարծում: Դա ճիշտ չէ:", language: 'hy')
103
+ expect(ps.segment).to eq(["Ոչ, այդպես չեմ կարծում:", "Դա ճիշտ չէ:"])
104
+ end
105
+
106
+ it 'correctly segments text #015' do
107
+ # "April 24 it has started to rain... I was thinking about." ==> ["April 24 it has started to rain... I was thinking about."]
108
+ ps = PragmaticSegmenter::Segmenter.new(text: "Ապրիլի 24-ին սկսեց անձրևել...Այդպես էի գիտեի:", language: 'hy')
109
+ expect(ps.segment).to eq(["Ապրիլի 24-ին սկսեց անձրևել...Այդպես էի գիտեի:"])
110
+ end
111
+
112
+ it 'correctly segments text #016' do
113
+ # "It was 1960...it was winter...it was night. It was cold...emptiness." ==> ["It was 1960...it was winter...it was night.", "It was cold...emptiness."]
114
+ ps = PragmaticSegmenter::Segmenter.new(text: "1960 թվական…ձմեռ…գիշեր: Սառն էր…դատարկություն:", language: 'hy')
115
+ expect(ps.segment).to eq(["1960 թվական…ձմեռ…գիշեր:", "Սառն էր…դատարկություն:"])
116
+ end
117
+
118
+ it 'correctly segments text #017' do
119
+ # "Why a computer could not do what a man could do? Simply it doesn't have a human brain." ==> ["Why a computer could not do what a man could do?", "Simply it doesn't have a human brain."]
120
+ ps = PragmaticSegmenter::Segmenter.new(text: "Ինչ՟ու այն, ինչ անում է մարդը, չի կարող անել համակարգիչը: Պարզապես չունի մարդկային ուղեղ:", language: 'hy')
121
+ expect(ps.segment).to eq(["Ինչ՟ու այն, ինչ անում է մարդը, չի կարող անել համակարգիչը:", "Պարզապես չունի մարդկային ուղեղ:"])
122
+ end
123
+
124
+ it 'correctly segments text #018' do
125
+ # "Numerate for me 3 things that are important for you - I answer love, knowledge, sincerity." ==> ["Numerate for me 3 things that are important for you - I answer love, knowledge, sincerity."]
126
+ ps = PragmaticSegmenter::Segmenter.new(text: "Թվարկիր ինձ համար 3 բան, որ կարևոր է քեզ համար - Պատասխանում եմ. սեր, գիտելիք, ազնվություն:", language: 'hy')
127
+ expect(ps.segment).to eq(["Թվարկիր ինձ համար 3 բան, որ կարևոր է քեզ համար - Պատասխանում եմ. սեր, գիտելիք, ազնվություն:"])
128
+ end
129
+
130
+ it 'correctly segments text #019' do
131
+ # "So, we are coming to the end. The logic is...simplicity and work" ==> ["So, we are coming to the end.", "Simplicity and work."]
132
+ ps = PragmaticSegmenter::Segmenter.new(text: "Այսպիսով` մոտենում ենք ավարտին: Տրամաբանությյունը հետևյալն է. պարզություն և աշխատանք:", language: 'hy')
133
+ expect(ps.segment).to eq(["Այսպիսով` մոտենում ենք ավարտին:", "Տրամաբանությյունը հետևյալն է. պարզություն և աշխատանք:"])
134
+ end
135
+
136
+ it 'correctly segments text #020' do
137
+ # "What are you thinking? Nothing!" ==> ["What are you thinking?", "Nothing!"]
138
+ ps = PragmaticSegmenter::Segmenter.new(text: "Ի՞նչ ես մտածում: Ոչինչ:", language: 'hy')
139
+ expect(ps.segment).to eq(["Ի՞նչ ես մտածում:", "Ոչինչ:"])
140
+ end
141
+
142
+ it 'correctly segments text #021' do
143
+ # "Can we work together ?. May be what you are thinking, is possible." ==> ["Can we work together?.", "May be what you are thinking is possible."]
144
+ ps = PragmaticSegmenter::Segmenter.new(text: "Կարող ե՞նք միասին աշխատել: Գուցե այն ինչ մտածում ես, իրականանալի է:", language: 'hy')
145
+ expect(ps.segment).to eq(["Կարող ե՞նք միասին աշխատել:", "Գուցե այն ինչ մտածում ես, իրականանալի է:"])
146
+ end
147
+
148
+ it 'correctly segments text #022' do
149
+ # "Now what we have started, comes to the end. However the questions are numerous... ." ==> ["Now what we have started, comes to the end.", "However the questions are numerous... ."]
150
+ ps = PragmaticSegmenter::Segmenter.new(text: "Հիմա, այն ինչ սկսել ենք, ավարտին է մոտենում: Հարցերը սակայն շատ են...:", language: 'hy')
151
+ expect(ps.segment).to eq(["Հիմա, այն ինչ սկսել ենք, ավարտին է մոտենում:", "Հարցերը սակայն շատ են...:"])
152
+ end
153
+
154
+ it 'correctly segments text #023' do
155
+ # "Honey... I am waiting. Shall I go... or?" ==> ["Honey... I am waiting.", "Shall I go... or?"]
156
+ ps = PragmaticSegmenter::Segmenter.new(text: "Սիրելիս...սպասում եմ: Գնամ թ՟ե …:", language: 'hy')
157
+ expect(ps.segment).to eq(["Սիրելիս...սպասում եմ:", "Գնամ թ՟ե …:"])
158
+ end
159
+ end
160
+ end