คุณสามารถแทนที่คำ "เสีย" เหล่านี้ส่วนใหญ่ด้วยต้นฉบับได้ คุณสามารถแทนที่คำได้อย่างปลอดภัยหาก:
- ชอบ
dene
หรือrey
ไม่ใช่คำจริง
- เหมือน
define
หรือfirefly
มีหนึ่งวิธีที่จะ sequeneces ใหม่เพิ่มมัด ( ff
, fi
, fl
, ffi
หรือffl
) และให้คำจริง
ปัญหาการมัดส่วนใหญ่จะเข้ากับเกณฑ์เหล่านี้ อย่างไรก็ตามคุณไม่สามารถแทนที่:
us
เพราะมันเป็นคำที่แท้จริงแม้ว่ามันอาจจะเป็นในตอนแรก fluffs
- ยัง
affirm
, butterfly
, fielders
, fortifies
, flimflam
, misfits
...
cus
เพราะมันอาจจะกลายเป็นอย่างใดอย่างหนึ่งcuffs
หรือficus
- ยัง
stiffed
/ stifled
, rifle
/ riffle
, flung
/ fluffing
...
ในนี้ 496 พันคำภาษาอังกฤษพจนานุกรมมี16055คำที่มีอย่างน้อยหนึ่งff
, fi
, fl
, ffi
หรือffl
ซึ่งกลายเป็น15,879คำเมื่อหนังสติ๊กของพวกเขาจะถูกลบออก 173คำที่หายไปเหล่านั้นเช่นชนcuffs
และficus
และที่ผ่านมา3เพราะพจนานุกรมที่มีคำff
, และfi
fl
790ของเหล่านี้ "มัดเอาออก" คำนี้เป็นคำจริงเหมือนus
แต่15089เป็นคำเสีย คำที่แตกหัก14960สามารถแทนที่ได้อย่างปลอดภัยด้วยคำเดิมซึ่งหมายถึง99.1%ของคำที่แตกหักนั้นสามารถแก้ไขได้และ93.2%ของคำเดิมที่มีการมัดรวมกันนั้นสามารถกู้คืนได้หลังจากคัดลอกไฟล์ PDF 6.8%ของคำที่มีลำดับการผูกจะหายไปจากการชน ( cus
) และคำย่อย ( us
) เว้นแต่คุณเลือกวิธี (บริบท / คำศัพท์เอกสาร?) เพื่อเลือกการแทนที่ที่ดีที่สุดสำหรับแต่ละคำที่ไม่มีการรับประกัน การแทนที่
ด้านล่างเป็นสคริปต์ Python ของฉันที่สร้างสถิติด้านบน คาดว่าไฟล์ข้อความพจนานุกรมที่มีหนึ่งคำต่อบรรทัด ในตอนท้ายมันเขียนไฟล์ CSV ที่จับคู่คำที่ไม่สามารถแก้ไขได้กับคำเดิม
นี่คือลิงค์สำหรับดาวน์โหลด CSV:
http://www.filedropper.com/brokenligaturewordfixes
รวมการแมปนี้เข้ากับสคริปต์การแทนที่ regex เพื่อแทนที่คำที่เสียหาย
import csv
import itertools
import operator
import re
dictionary_file_path = 'dictionary.txt'
broken_word_fixes_file_path = 'broken_word_fixes.csv'
ligatures = 'ffi', 'ffl', 'ff', 'fi', 'fl'
with open(dictionary_file_path, 'r') as dictionary_file:
dictionary_words = list(set(line.strip()
for line in dictionary_file.readlines()))
broken_word_fixes = {}
ligature_words = set()
ligature_removed_words = set()
broken_words = set()
multi_ligature_words = set()
# Find broken word fixes for words with one ligature sequence
# Example: "dene" --> "define"
words_and_ligatures = list(itertools.product(dictionary_words, ligatures))
for i, (word, ligature) in enumerate(words_and_ligatures):
if i % 50000 == 0:
print('1-ligature words {percent:.3g}% complete'
.format(percent=100 * i / len(words_and_ligatures)))
for ligature_match in re.finditer(ligature, word):
if word in ligature_words:
multi_ligature_words.add(word)
ligature_words.add(word)
if word == ligature:
break
# Skip words that contain a larger ligature
if (('ffi' in word and ligature != 'ffi') or
('ffl' in word and ligature != 'ffl')):
break
# Replace ligatures with dots to avoid creating new ligatures
# Example: "offline" --> "of.ine" to avoid creating "fi"
ligature_removed_word = (word[:ligature_match.start()] +
'.' +
word[ligature_match.end():])
# Skip words that contain another ligature
if any(ligature in ligature_removed_word for ligature in ligatures):
continue
ligature_removed_word = ligature_removed_word.replace('.', '')
ligature_removed_words.add(ligature_removed_word)
if ligature_removed_word not in dictionary_words:
broken_word = ligature_removed_word
broken_words.add(broken_word)
if broken_word not in broken_word_fixes:
broken_word_fixes[broken_word] = word
else:
# Ignore broken words with multiple possible fixes
# Example: "cus" --> "cuffs" or "ficus"
broken_word_fixes[broken_word] = None
# Find broken word fixes for word with multiple ligature sequences
# Example: "rey" --> "firefly"
multi_ligature_words = sorted(multi_ligature_words)
numbers_of_ligatures_in_word = 2, 3
for number_of_ligatures_in_word in numbers_of_ligatures_in_word:
ligature_lists = itertools.combinations_with_replacement(
ligatures, r=number_of_ligatures_in_word
)
words_and_ligature_lists = list(itertools.product(
multi_ligature_words, ligature_lists
))
for i, (word, ligature_list) in enumerate(words_and_ligature_lists):
if i % 1000 == 0:
print('{n}-ligature words {percent:.3g}% complete'
.format(n=number_of_ligatures_in_word,
percent=100 * i / len(words_and_ligature_lists)))
# Skip words that contain a larger ligature
if (('ffi' in word and 'ffi' not in ligature_list) or
('ffl' in word and 'ffl' not in ligature_list)):
continue
ligature_removed_word = word
for ligature in ligature_list:
ligature_matches = list(re.finditer(ligature, ligature_removed_word))
if not ligature_matches:
break
ligature_match = ligature_matches[0]
# Replace ligatures with dots to avoid creating new ligatures
# Example: "offline" --> "of.ine" to avoid creating "fi"
ligature_removed_word = (
ligature_removed_word[:ligature_match.start()] +
'.' +
ligature_removed_word[ligature_match.end():]
)
else:
# Skip words that contain another ligature
if any(ligature in ligature_removed_word for ligature in ligatures):
continue
ligature_removed_word = ligature_removed_word.replace('.', '')
ligature_removed_words.add(ligature_removed_word)
if ligature_removed_word not in dictionary_words:
broken_word = ligature_removed_word
broken_words.add(broken_word)
if broken_word not in broken_word_fixes:
broken_word_fixes[broken_word] = word
else:
# Ignore broken words with multiple possible fixes
# Example: "ung" --> "flung" or "fluffing"
broken_word_fixes[broken_word] = None
# Remove broken words with multiple possible fixes
for broken_word, fixed_word in broken_word_fixes.copy().items():
if not fixed_word:
broken_word_fixes.pop(broken_word)
number_of_ligature_words = len(ligature_words)
number_of_ligature_removed_words = len(ligature_removed_words)
number_of_broken_words = len(broken_words)
number_of_fixable_broken_words = len(
[word for word in set(broken_word_fixes.keys())
if word and broken_word_fixes[word]]
)
number_of_recoverable_ligature_words = len(
[word for word in set(broken_word_fixes.values())
if word]
)
print(number_of_ligature_words, 'ligature words')
print(number_of_ligature_removed_words, 'ligature-removed words')
print(number_of_broken_words, 'broken words')
print(number_of_fixable_broken_words,
'fixable broken words ({percent:.3g}% fixable)'
.format(percent=(
100 * number_of_fixable_broken_words / number_of_broken_words
)))
print(number_of_recoverable_ligature_words,
'recoverable ligature words ({percent:.3g}% recoverable)'
'(for at least one broken word)'
.format(percent=(
100 * number_of_recoverable_ligature_words / number_of_ligature_words
)))
with open(broken_word_fixes_file_path, 'w+', newline='') as broken_word_fixes_file:
csv_writer = csv.writer(broken_word_fixes_file)
sorted_broken_word_fixes = sorted(broken_word_fixes.items(),
key=operator.itemgetter(0))
for broken_word, fixed_word in sorted_broken_word_fixes:
csv_writer.writerow([broken_word, fixed_word])