Следите за положением слова при цикле wx.TextCtrl.GetValue (), чтобы включить процесс повторяющихся слов - PullRequest
0 голосов
/ 20 марта 2020

Я пытался сделать проверку орфографии в wx Python GUI, но у меня возникают проблемы в тех случаях, когда у меня есть повторяющиеся орфографические ошибки. Функция должна установить слова красным цветом, а затем предложить исправление в MessageDialog . Все это хорошо работает с предложениями по исправлению MessageDialog , но я не могу sh изменить цвет повторяющегося орфографического слова. Я понимаю, что проблема в том, что когда я получаю начальную позицию слова ... он продолжает учитывать первое вхождение слова и игнорирует другие.

for i in range(self.tx_input.GetNumberOfLines()):
            line = self.tx_input.GetLineText(i)
            for word in text:
                if word in line and word not in suggestion:
                    startPos = self.tx_input.GetValue().find(word)
                    endPos = startPos + len(word)
                    self.tx_input.SetStyle(startPos, endPos, wx.TextAttr("red", "white")) 

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

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


Полный код

class AddQuestion ( wx.Frame ):

    def __init__(self,parent):

        wx.Frame.__init__(self,parent,id=wx.ID_ANY, title='Grammar Checker', pos=wx.DefaultPosition, size=wx.Size(350,350), style=wx.DEFAULT_FRAME_STYLE)
        self.SetBackgroundColour( wx.Colour( 0, 93, 126 ))
        panel = wx.Panel(self)
        mainBox = wx.BoxSizer(wx.VERTICAL)
        panel.SetSizer(mainBox)

        self.tx_input = wx.TextCtrl(panel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size(350,150), wx.TE_MULTILINE|wx.TE_RICH2)
        mainBox.Add( self.tx_input, 1, wx.ALL|wx.EXPAND, 5 )

        btnBox = wx.BoxSizer(wx.VERTICAL)
        self.btn = wx.Button(panel, wx.ID_ANY,u'Grammar Check', wx.DefaultPosition, wx.DefaultSize,0)
        btnBox.Add(self.btn,0,wx.ALL,5)

        mainBox.Add(btnBox,0,wx.ALL|wx.ALIGN_CENTER,5)

        self.btn.Bind(wx.EVT_BUTTON, self.grammarCheck)

    def warn(self, parent, message, caption = 'WARNING!'):
        dlg = wx.MessageDialog(parent, message, caption, wx.OK | wx.ICON_WARNING)
        dlg.ShowModal()
        dlg.Destroy()

    def grammarCheck(self, event):

        from symspellpy import SymSpell

        sym_spell = SymSpell()
        sym_spell.load_dictionary("frequency_dictionary_en_82_765.txt", 0, 1)
        input_term = self.tx_input.GetValue().lower()
        # filter unecessary character
        ignore = r'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~1234567890“”–'
        text = sym_spell.word_segmentation(input_term.translate(str.maketrans("","",ignore)), max_edit_distance=2 ).segmented_string.split()
        suggestion = sym_spell.word_segmentation(input_term.translate(str.maketrans("","",ignore)), max_edit_distance=2 ).corrected_string.split()

        for i in range(self.tx_input.GetNumberOfLines()):
            line = self.tx_input.GetLineText(i)
            for word in text:
                if word in line and word not in suggestion:
                    startPos = self.tx_input.GetValue().find(word)
                    endPos = startPos + len(word)
                    self.tx_input.SetStyle(startPos, endPos, wx.TextAttr("red", "white"))

        for i in range(len(text)):
            if text[i] != suggestion[i]:
                self.warn(self, "`" + text[i] + "`" + " did you mean " + "`" + suggestion[i] + "` ?")


if __name__ == '__main__':

        app = wx.App(False)
        frame = AddQuestion(None)
        frame.Show()

        app.MainLoop() 

1 Ответ

0 голосов
/ 21 марта 2020

Вы всегда ищете первое вхождение, используя string.find(word)
Найдите что-то вроде "python найти все вхождения подстроки", я нашел:

# using list comprehension + startswith() 
# All occurrences of substring in string  
res = [i for i in range(len(test_str)) if test_str.startswith(test_sub, i)] 

и

import re

# using re.finditer() 
# All occurrences of substring in string  
res = [i.start() for i in re.finditer(test_sub, test_str)] 

оба возвращают список начальных позиций в тестовой строке и могут быть адаптированы к вашему коду

...