按字母将字符串拆分成片段。

3
我想将给定的字符串分割成包含在该字符串中的字母段。例如,如果给定以下字符串:
Los eventos automovilísticos comenzaron poco después de la construcción exitosa de los primeros automóviles a gasolina. El veloz zorro marrón saltó sobre el perezoso perro.

Motoring events began soon after the construction of the first successful gasoline-fueled automobiles. The quick brown fox jumped over the lazy dog.

Мотори су почели убрзо након изградње првих успешних аутомобила на бензин.Брза смеђа лисица је прескочила лењог пса.

Автомобилните събития започнаха скоро след конструирането на първите успешни автомобили с бензиново гориво. Бързата кафява лисица прескочи мързеливото куче.

自動車イベントは、最初の成功したガソリン燃料自動車の製造直後に始まりました。 素早い茶色のキツネは怠け者の犬を飛び越えました。

بدأت أحداث السيارات بعد وقت قصير من بناء أول سيارة ناجحة تعمل بالبنزين. قفز الثعلب البني السريع فوق الكلب الكسول.

上述文本包含西班牙语、英语、塞尔维亚语、保加利亚语、日语、阿拉伯语段落(语言顺序遵循段落顺序)。

然后,经过应用某些魔术函数后,我希望得到以下输出:

{
    "langs": [
        {
            "alphabet": "latin",
            "text": "Los eventos automovilísticos comenzaron poco después de la construcción exitosa de los primeros automóviles a gasolina. El veloz zorro marrón saltó sobre el perezoso perro. Motoring events began soon after the construction of the first successful gasoline-fueled automobiles. The quick brown fox jumped over the lazy dog."
        },
        {
            "alphabet": "cyrillic",
            "text": "Мотори су почели убрзо након изградње првих успешних аутомобила на бензин.Брза смеђа лисица је прескочила лењог пса. Автомобилните събития започнаха скоро след конструирането на първите успешни автомобили с бензиново гориво. Бързата кафява лисица прескочи мързеливото куче."
        },
        {
            "alphabet": "japanese",
            "text": "自動車イベントは、最初の成功したガソリン燃料自動車の製造直後に始まりました。 素早い茶色のキツネは怠け者の犬を飛び越えました。"
        },
        {
            "alphabet": "arabic",
            "text": "بدأت أحداث السيارات بعد وقت قصير من بناء أول سيارة ناجحة تعمل بالبنزين. قفز الثعلب البني السريع فوق الكلب الكسول."
        }
    ]
}

正如您所见,一些语言按其家族字母表进行分组。例如,西班牙语和英语段落被归为拉丁语系,塞尔维亚语和保加利亚语段落被归为西里尔语系。这是因为很难找到特定的语言(因为大多数字母在不同语言之间是共享的)。

理想情况下,我的最终输出应该像这样:

{
    "langs": [
        {
            "lang": "spanish",
            "text": "Los eventos automovilísticos comenzaron poco después de la construcción exitosa de los primeros automóviles a gasolina. El veloz zorro marrón saltó sobre el perezoso perro."
        },
        {
            "lang": "english",
            "text": "Motoring events began soon after the construction of the first successful gasoline-fueled automobiles. The quick brown fox jumped over the lazy dog."
        },
        {
            "lang": "serbian",
            "text": "Мотори су почели убрзо након изградње првих успешних аутомобила на бензин.Брза смеђа лисица је прескочила лењог пса."
        },
        {
            "lang": "bulgarian",
            "text":"Автомобилните събития започнаха скоро след конструирането на първите успешни автомобили с бензиново гориво. Бързата кафява лисица прескочи мързеливото куче."
        },
        {
            "lang": "japanese",
            "text": "自動車イベントは、最初の成功したガソリン燃料自動車の製造直後に始まりました。 素早い茶色のキツネは怠け者の犬を飛び越えました。"
        },
        {
            "lang": "arabic",
            "text": "بدأت أحداث السيارات بعد وقت قصير من بناء أول سيارة ناجحة تعمل بالبنزين. قفز الثعلب البني السريع فوق الكلب الكسول."
        }
    ]
}

我需要根据语言将文本拆分成子字符串。为此,我计划使用cld2,它可以将文本拆分成句子,但根据我的实验,当字符串包含混合字母的文本时(即西里尔文+日语等),它表现不佳。然而,cld2在共享字母族的混合语言文本上表现良好(即法语+英语等)。

因此,我计划按字母族将文本拆分成子字符串,然后对于每个字母族,我将应用cld2来预测具体的语言。

另一个重要的要求:

  • 混合语言可能不像上面的示例那样明确地分隔开(我之所以这样做是为了简单起见并使问题更清晰)
  • 我需要能够“离线”执行此操作,而无需连接到第三方服务器(例如Google等),因为需要处理大量数据

如果您对上述问题有任何想法,我将不胜感激。提前致谢。


1
我认为问题的一个重要部分与字符编码有关。输入是如何提供的?我对此并不是很了解,但我认为UTF*规范可以回答问题的第一部分。 - Erwan
输入只是一个文本。我的意思是,我们可以使用任何方法(utf-8、utf-16等)根据下一步所需的格式进行编码。我知道我们可以通过某种手动方式来完成这个过程,即将每个字符检查到字母表范围之一,然后做出一些假设。但这种方式不太高效(可能甚至嵌套循环)且容易出错(因为可能存在“if”情况)。我想知道是否有一些机器学习的方法可以更快速、更少出错地完成这个过程。 - Sirojiddin Komolov
我不知道文本的来源,但并非所有文本都可以用任何编码表示。实际上,文本能够正确表示和用于机器学习的事实是其正确编码的结果,因此字符集(拉丁文、阿拉伯文等)可能可以直接确定。理论上,使用确定性方法应该更快、更安全,但编码可能会更麻烦 ;) - Erwan
1个回答

3
以下解决方案使用了谷歌翻译。请确保您使用pip install googletrans==4.0.0-rc1来安装4.0.0版本候选版,以避免潜在问题。在撰写本文时,其他语言检测包(如langdetectspacy_langdetect)无法区分塞尔维亚语和马其顿语。
请注意,我经验中的所有语言检测模块都符合ISO 639-1语言代码,因此输出将使用这些代码。如果您需要实际语言名称(例如“西班牙语”而不是“es”),则必须编写一个简单的循环,使用生成的languageDict进行转换。我认为这个问题并不是主要问题,因此选择省略它。
作为一个附带说明,如果你需要根据字母表对各种语言进行分组,这也可以通过使用生成的languageDict进行简单循环来完成。将ISO 639-1语言代码按其字母表归类,然后根据程序分类文本。
from googletrans import Translator
from collections import defaultdict

text = """
Los eventos automovilísticos comenzaron poco después de la construcción exitosa de los primeros automóviles a gasolina. El veloz zorro marrón saltó sobre el perezoso perro.

Motoring events began soon after the construction of the first successful gasoline-fueled automobiles. The quick brown fox jumped over the lazy dog.

Мотори су почели убрзо након изградње првих успешних аутомобила на бензин.Брза смеђа лисица је прескочила лењог пса.

An additional English sentence to see how it handles this.

Автомобилните събития започнаха скоро след конструирането на първите успешни автомобили с бензиново гориво. Бързата кафява лисица прескочи мързеливото куче.

自動車イベントは、最初の成功したガソリン燃料自動車の製造直後に始まりました。 素早い茶色のキツネは怠け者の犬を飛び越えました。

بدأت أحداث السيارات بعد وقت قصير من بناء أول سيارة ناجحة تعمل بالبنزين. قفز الثعلب البني السريع فوق الكلب الكسول.
"""

translator = Translator()  # Instantiate google translator
languageDict = defaultdict(list)  # Create default dictionary to elegantly store results
for line in text.splitlines():  # Iterate over text split by lines
    if line != '':  # Ignore blank lines
        detectedLang = translator.detect(line).lang  # Detect language
        languageDict[detectedLang].append(line)  # Store line under corresponding language key
print(dict(languageDict))

输出

{
'es': ['Los eventos automovilísticos comenzaron poco después de la construcción exitosa de los primeros automóviles a gasolina. El veloz zorro marrón saltó sobre el perezoso perro.'], 
'en': ['Motoring events began soon after the construction of the first successful gasoline-fueled automobiles. The quick brown fox jumped over the lazy dog.', 'An additional English sentence to see how it handles this.'], 
'sr': ['Мотори су почели убрзо након изградње првих успешних аутомобила на бензин.Брза смеђа лисица је прескочила лењог пса.'], 
'bg': ['Автомобилните събития започнаха скоро след конструирането на първите успешни автомобили с бензиново гориво. Бързата кафява лисица прескочи мързеливото куче.'], 
'ja': ['自動車イベントは、最初の成功したガソリン燃料自動車の製造直後に始まりました。 素早い茶色のキツネは怠け者の犬を飛び越えました。'], 
'ar': ['بدأت أحداث السيارات بعد وقت قصير من بناء أول سيارة ناجحة تعمل بالبنزين. قفز الثعلب البني السريع فوق الكلب الكسول.']
}

非常感谢您提供的解决方案。我想我忘记了指定其他重要的要求。因此,我需要能够在“离线”状态下进行操作,而不连接到第三方服务器(因为有大量需要处理的数据)。另一个重要的要求是,混合语言可能没有明确的行分隔符(我这样做是为了简单起见并使问题清晰明了)。我还编辑了问题以考虑这些要求。 - Sirojiddin Komolov
1
@SirojiddinKomolov 在这种情况下,一些能够在离线环境中检测混合输入语言的不错的库包括polyglotpycld2这个问题及其答案提供了一个全面的选项列表。 - Kyle F Hartzenberg
1
谢谢您提供的有用链接。我认为我可以通过cld2库的一些技巧取得一些好的结果。让我试试看。 - Sirojiddin Komolov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接