Ich löse 100 Klopfen bei der Sprachverarbeitung in einer Lernsitzung, die sich auf interne Mitglieder, aber den Antwortcode und die Lösung konzentriert Dies ist eine Zusammenfassung der Tricks, die ich dabei nützlich fand. Der größte Teil des Inhalts wurde von mir selbst untersucht und verifiziert, enthält jedoch auch Informationen, die von anderen Mitgliedern der Studiengruppe geteilt wurden.
Diesmal ist es ein regulärer Ausdruck, aber es gab eine Antwort vom Grundinhalt auf die schwierigen und schwierigen Probleme.
Ich hatte bisher keine Gelegenheit, reguläre Ausdrücke ernsthaft zu lernen, daher habe ich das Grundwissen im Voraus überprüft, aber Original Python Document Die Seiten /re.html) und WWW Creators sind einfach zu lesen und zu organisieren, was mir geholfen hat. Einige der Tutorial-ähnlichen Dokumente wurden vom Ruby-Experten Mr. Ito verfasst. Dies kann hilfreich sein, wenn Sie nicht weiterkommen.
Legen Sie jawiki-country.json.gz
in dasselbe Verzeichnis wie die ipynb- (oder Python-) Datei
!gzip -d jawiki-country.json.gz
Dann können Sie die Zip entpacken.
import json
def load_uk():
with open('jawiki-country.json') as file:
for item in file:
d = json.loads(item)
if d['title'] == 'England':
return d['text']
print(load_uk())
Ergebnis
{{redirect|UK}}
{{Grundlegende Informationen Land
|Kurzbezeichnung=England
|Japanischer Ländername=Vereinigtes Königreich Großbritannien und Nordirland
|Offizieller Ländername= {{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>Offizieller Ländername außer Englisch:<br/>
...
import re
def extract_categ_lines():
return re.findall(r'.*Category.*', load_uk())
print(*extract_categ_lines())
Ergebnis
[[Category:England|*]] [[Category:Königreich des Vereinigten Königreichs|*]] [[Category:G8-Mitgliedsländer]] [[Category:Mitgliedsländer der Europäischen Union]] [[Category:Marine Nation]] [[Category:Souveränes Land]] [[Category:Inselstaat|Kureito Furiten]] [[Category:Staat / Region gegründet 1801]]
Da die Problemanweisung das Wort "Zeilen extrahieren" enthält, möchte ich "split ()" verwenden, um den Rückgabewert von "load_uk ()" für jede Zeile zu trennen, aber eine solche Verarbeitung ist unerlässlich. Ist nicht. .
Stellt" jedes Zeichen außer Zeilenumbrüchen "dar. Wenn Sie also wie oben schreiben, können Sie nur die Zeile abrufen, die die Zeichenfolge" Kategorie "enthält.
def extract_categs():
return re.findall(r'.*Category:(.*?)\]', load_uk())
print(*extract_categs())
Ergebnis
England|*Königreich des Vereinigten Königreichs|*G8-Mitgliedsländer EU-Mitgliedsländer Seeländer Souveräne Länder Inselstaaten|Kureito Furiten Staat / Region Gegründet 1801
Fügen Sie "()" ein, um die Zeichenfolge unmittelbar nach "Kategorie:" zu erfassen. Ich habe jedoch ein "?" Nach dem "*" hinzugefügt, um es nicht gierig zu machen (geben Sie die kürzeste Übereinstimmung an), damit das "]" dahinter nicht zusammengenommen wird.
def extract_sects():
tuples = re.findall(r'(={2,})\s*([^\s=]*).*', load_uk())
sects = []
for t in tuples:
if t[0] == '==':
sects.append([t[1], 1])
elif t[0] == '===':
sects.append([t[1], 2])
elif t[0] == '====':
sects.append([t[1], 3])
return sects
print(*extract_sects())
Ergebnis
['Ländername', 1] ['Geschichte', 1] ['Erdkunde', 1] ['Klima', 2] ['Politik', 1] ['Diplomatie und Militär', 1] ['Abteilung für lokale Verwaltung', 1] ['Großstädte', 2] ['Wissenschaft und Technik', 1] ['Wirtschaft', 1] ['Bergbau', 2] ['Landwirtschaft', 2] ['Handel', 2] ['Währung', 2] ['Unternehmen', 2] ['der Verkehr', 1] ['Straße', 2] ['Eisenbahn', 2] ['Versand', 2] ['Luftfahrt', 2] ['Kommunikation', 1] ['Menschen', 1] ['Sprache', 2] ['Religion', 2] ['Ehe', 2] ['Bildung', 2] ['Kultur', 1] ['食Kultur', 2] ['Literatur', 2] ['Philosophie', 2] ['Musik', 2] ['イギリスのポピュラーMusik', 3] ['Filme', 2] ['Komödie', 2] ['Nationalblume', 2] ['Weltkulturerbe', 2] ['Ferien', 2] ['Sport', 1] ['Fußball', 2] ['Pferderennen', 2] ['モーターSport', 2] ['Fußnote', 1] ['Verwandte Artikel', 1] ['Externer Link', 1]
Da "^ \ s =" "jedes Zeichen bedeutet, das weder leer noch" = "ist, bedeutet" [^ \ s =] + "" ein oder mehrere beliebige Zeichen, die weder leer noch "=" sind. Es bedeutet "Dinge". Dies ist der Abschnittsname. Dies ist der erste Wert, den Sie dieses Mal erhalten möchten. Wenn Sie außerdem "= {2,}" in "()" einschließen, können Sie "zwei oder mehr" = "in einer Reihe" erhalten.
Für jede Übereinstimmung wird ein Taple zurückgegeben, das die beiden oben genannten Werte enthält. Daher habe ich ihn verwendet, um den Rückgabewert mit der Anweisung "for" zu erstellen. Ich muss mich nicht um das Format des Rückgabewerts kümmern, da dieser nicht angegeben ist, aber ich habe ihn als Array von Arrays ausgewählt.
Übrigens bereite ich im obigen Code zuerst eine Liste mit dem Namen "Sekten" vor, füge Elemente ein und gebe sie am Ende zurück, aber die Verwendung von "Ertrag" macht das etwas prägnanter. Kann geschrieben werden.
def extract_sects_2():
tuples = re.findall(r'(={2,})\s*([^\s=]+).*', load_uk())
for t in tuples:
if t[0] == '==':
yield [t[1], 1]
elif t[0] == '===':
yield [t[1], 2]
elif t[0] == '====':
yield [t[1], 3]
print(*extract_sects_2())
Eine Funktion, die "Yield" verwendet, wird als Generator bezeichnet und gibt einen Iterator (Generatoriterator) zurück (Einzelheiten finden Sie in der Python-Dokumentation. Siehe # term-generator)), es scheint, dass der Iterator wie oben beschrieben mit einem "*" davor erweitert oder in eine Liste konvertiert werden kann, indem er an "list ()" übergeben wird.
def extract_media_files():
return re.findall(r'(?:File|Datei):(.+?)\|', load_uk())
extract_media_files()
Ergebnis
['Royal Coat of Arms of the United Kingdom.svg',
'Battle of Waterloo 1815.PNG',
'The British Empire.png',
'Uk topo en.jpg',
'BenNevis2005.jpg',
...
Ich muss "()" verwenden, um "" Datei "oder" Datei "darzustellen, aber ich möchte dies nicht erfassen, also schrieb ich"?: "Unmittelbar nach" ("?
Der Grund, warum print ()
in der letzten Zeile nicht verwendet wird, ist übrigens, dass Jupyter diese ohne Erlaubnis formatiert und dann ausgibt, wenn Sie hier eine Liste usw. zurückgeben.
def extract_template():
data = re.search(r'\{\{Grundinformation.*\n\}\}', load_uk(), re.DOTALL).group()
tuples = re.findall(r'\n\|(.+?)\s=\s(.+?)(?:(?=\n\|)|(?=\}\}\n))', data, re.DOTALL)
return dict(tuples)
extract_template()
Ergebnis
{'Kurzbezeichnung': '',
'': '',
'': '{{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>:<br/>\n*{{lang|gd|An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn mu Thuath}}([[]])<br/>\n*{{lang|cy|Teyrnas Gyfunol Prydain Fawr a Gogledd Iwerddon}}([[Japanischer Ländername Großbritannien und Nordirland Vereinigtes Königreich Offizieller Ländername Nicht englischer offizieller Ländername Schottisch-Gälisch Walisisch]])<br/>\n*{{lang|ga|Ríocht Aontaithe na Breataine Móire agus Tuaisceart na hÉireann}}([[irisch]])<br/>\n*{{lang|kw|An Rywvaneth Unys a Vreten Veur hag Iwerdhon Glédh}}([[Cornwall]])<br/>\n*{{lang|sco|Unitit Kinrick o Great Breetain an Northren Ireland}}([[schottisch]])<br/>\n**{{lang|sco|Claught Kängrick o Docht Brätain an Norlin Airlann}}、{{lang|sco|Unitet Kängdom o Great Brittain an Norlin Airlann}}(アルスター・schottisch)</ref>',
...
'Internationale Telefonnummer': '44'}
Persönlich war es das schwierigste Thema in diesem Kapitel. Ich habe jedoch den Prozess der Not gelernt, daher werde ich etwas mehr über den Kern des Problems schreiben, "re.findall ()". Wenn Sie darüber nachdenken, welche Art von regulärem Ausdruck hier verwendet werden soll, wahrscheinlich zuerst
re.findall(r'\n\|(.+)\s=\s(.+)\n\|', data)
Ich denke, ein Code wie dieser kommt mir in den Sinn. Wenn Sie dies tun, werden Sie jedoch feststellen, dass die gleichmäßig geordneten Teile wie "Japanischer Ländername": "Großbritannien und das Vereinigte Königreich Nordirland" nicht übernommen werden. Die Ursache dafür ist
\n|Kurzbezeichnung=England\n|Japanischer Ländername
Wenn es eine Zeichenfolge wie gibt, wenn es sich um den obigen regulären Ausdruck handelt\n|Kurzbezeichnung=England\n|
Suchen Sie nach einem Spiel nach dem nächsten SpielTag
Dies liegt daran, dass es die Zeichenfolge danach wirdDokumentWennSiedenobigenAusdruckverwenden,lautetderobigereguläreAusdruckTag
Vordem\n|
Funktioniertnicht,weiles"verbraucht").
Also was tun?\n|
Es gibt eine Methode namens "Look-Ahead", um den Verbrauch von zu verhindern. Als Code der reguläre Ausdruck\n\|
Zu(?=)
Schließen Sie es ein und gehen Sie wie folgt vor.
re.findall(r'\n\|(.+)\s=\s(.+)(?=\n\|)', load_uk())
Wenn Sie es damit erneut ausführen, sollten Sie in der Lage sein, die Zeilen wie "Japanischer Ländername" richtig abzurufen. Wenn Sie sich jedoch die hier erhaltene Zeichenfolge genau ansehen, ist nur die erste Zeile enthalten, in der der offizielle Ländername erläutert wird. Dies bedeutet, dass das im zweiten ()
geschriebene . +
Mit einem oder mehreren beliebigen Zeichen außer dem Zeilenvorschub (\ n
) übereinstimmt. Mit anderen Worten, es ist nicht möglich, über Linien hinwegzukommen.
Übergeben Sie daher ein Modul namens "re.DOTALL" an "findall ()". Dann ruft . +
"Ein oder mehrere beliebige Zeichen" ab, aber wenn Sie +
gierig lassen, erhalten Sie zu viel. Fügen wir am Ende ein "?" Hinzu.
re.findall(r'\n\|(.+?)\s=\s(.+?)(?=\n\|)', load_uk(), re.DOTALL)
Ich denke, das ist ungefähr in Ordnung, aber wenn Sie sich die zurückgegebenen Ergebnisse genau ansehen, gibt es ein Problem, dass Sie am Ende zu viel bekommen. Schauen Sie sich daher die Zeichenfolge nach dem Muster an und ändern Sie sie wie folgt, damit sie auch dann übereinstimmt, wenn sie "}} \ n" ist.
re.findall(r'\n\|(.+?)\s=\s(.+?)(?:(?=\n\|)|(?=\}\}\n))', data, re.DOTALL)
Damit habe ich endlich den Code geschrieben, der die Spezifikation der Problemstellung erfüllt, aber wenn ich das Gefühl habe, zu viele Dinge in eine Zeile gepackt zu haben, kann ich die Zeilen wie folgt mit "re.complile ()" trennen. Überlegen.
pattern = re.compile(r'\n\|(.+?)\s=\s(.+?)(?:(?=\n\|)|(?=\}\}\n))', re.DOTALL)
tuples = pattern.findall(data)
Wenn Sie einen Zeilenumbruch in den Teil mit regulären Ausdrücken einfügen möchten, können Sie nach "re.DOTALL" "+ re.MULTILINE" hinzufügen.
def remove_emphases():
d = extract_template()
return {key: re.sub(r'\'{2,5}', '', val) for key, val in d.items()}
remove_emphases()
Ergebnis
{'Kurzbezeichnung': 'England',
'Japanischer Ländername': 'Vereinigtes Königreich Großbritannien und Nordirland',
'Offizieller Ländername': '{{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>Offizieller Ländername außer Englisch:<br/>\n*{{lang|gd|An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn mu Thuath}}([[schottisch Gälisch]])<br/>\n*{{lang|cy|Teyrnas Gyfunol Prydain Fawr a Gogledd Iwerddon}}([[Wales]])<br/>\n*{{lang|ga|Ríocht Aontaithe na Breataine Móire agus Tuaisceart na hÉireann}}([[irisch]])<br/>\n*{{lang|kw|An Rywvaneth Unys a Vreten Veur hag Iwerdhon Glédh}}([[Cornwall]])<br/>\n*{{lang|sco|Unitit Kinrick o Great Breetain an Northren Ireland}}([[schottisch]])<br/>\n**{{lang|sco|Claught Kängrick o Docht Brätain an Norlin Airlann}}、{{lang|sco|Unitet Kängdom o Great Brittain an Norlin Airlann}}(アルスター・schottisch)</ref>',
...
'Etablierte Form 4': 'Geändert in den aktuellen Ländernamen "Großbritannien und das Vereinigte Königreich Nordirland"',
...
Im Vergleich zu 25 sind reguläre Ausdrücke ein Problem, das nur mit Grundkenntnissen gelöst werden kann. Es gibt jedoch eine Einschränkung, dass es in einigen Fällen nicht funktioniert, wenn Sie ein Leerzeichen nach "2" setzen.
Ich denke, die Einschlussnotation im Wörterbuch ist eine Python-spezifische Notation, aber wenn ich mich daran gewöhne, kann ich sie präzise schreiben, sodass ich sie oft persönlich verwende.
def remove_links():
d = remove_emphases()
return {key: re.sub(r'\[\[.*?\|?(.+?)\]\]', r'\\1', val) for key, val in d.items()}
remove_links()
Ergebnis
{'Kurzbezeichnung': 'England',
'Japanischer Ländername': 'Vereinigtes Königreich Großbritannien und Nordirland',
'Offizieller Ländername': '{{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>Offizieller Ländername außer Englisch:<br/>\n*{{lang|gd|An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn mu Thuath}}(Schottisch Gälisch)<br/>\n*{{lang|cy|Teyrnas Gyfunol Prydain Fawr a Gogledd Iwerddon}}(Wales)<br/>\n*{{lang|ga|Ríocht Aontaithe na Breataine Móire agus Tuaisceart na hÉireann}}(Irisch)<br/>\n*{{lang|kw|An Rywvaneth Unys a Vreten Veur hag Iwerdhon Glédh}}(Cornwall)<br/>\n*{{lang|sco|Unitit Kinrick o Great Breetain an Northren Ireland}}(Schottisch)<br/>\n**{{lang|sco|Claught Kängrick o Docht Brätain an Norlin Airlann}}、{{lang|sco|Unitet Kängdom o Great Brittain an Norlin Airlann}}(Ulster Scottish)</ref>',
'Flaggenbild': 'Flag of the United Kingdom.svg',
'Nationales Emblembild': 'Datei:Royal Coat of Arms of the United Kingdom.svg|85px|Britisches nationales Emblem',
...
Was willst du tun[[]]
Wenn ein Teil von umgeben ist, nehmen Sie den Inhalt heraus. Allerdings darin|
Wenn da ist|
Ich habe versucht, es zu lösen, indem ich "nur die Rückseite herausnehmen" definiert habe.|
Ich weiß nicht, ob es herauskommt oder nicht, also dahinter?
Wird hinzugefügt, um anzugeben, dass es 0 oder 1 Wiederholung entspricht.
def remove_markups():
d = remove_links()
#Entfernen Sie externe Links
d = {key: re.sub(r'\[http:.+?\s(.+?)\]', '\\1', val) for key, val in d.items()}
#Entfernen Sie ref (Start- und End-Tags) und br
d = {key: re.sub(r'</?(ref|br).*?>', '', val) for key, val in d.items()}
return d
remove_markups()
Ergebnis
{'Kurzbezeichnung': 'England',
'Japanischer Ländername': 'Vereinigtes Königreich Großbritannien und Nordirland',
'Offizieller Ländername': '{{lang|en|United Kingdom of Great Britain and Northern Ireland}}Offizieller Ländername außer Englisch:\n*{{lang|gd|An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn mu Thuath}}(Schottisch Gälisch)\n*{{lang|cy|Teyrnas Gyfunol Prydain Fawr a Gogledd Iwerddon}}(Wales)\n*{{lang|ga|Ríocht Aontaithe na Breataine Móire agus Tuaisceart na hÉireann}}(Irisch)\n*{{lang|kw|An Rywvaneth Unys a Vreten Veur hag Iwerdhon Glédh}}(Cornwall)\n*{{lang|sco|Unitit Kinrick o Great Breetain an Northren Ireland}}(Schottisch)\n**{{lang|sco|Claught Kängrick o Docht Brätain an Norlin Airlann}}、{{lang|sco|Unitet Kängdom o Great Brittain an Norlin Airlann}}(Ulster Scottish)',
'Flaggenbild': 'Flag of the United Kingdom.svg',
...
'Bevölkerungswert': '63,181,775United Nations Department of Economic and Social Affairs>Population Division>Data>Population>Total Population',
...
{{lang|.+?|.+?}}
Ich dachte, dass Muster wie dieses entfernt werden sollten,~~ich werde müde~~Es wurde nicht in der Kurzreferenztabelle aufgeführt, daher habe ich es so belassen, wie es diesmal ist.
import requests
import json
def get_flag_url():
d = remove_markup()['Flaggenbild']
url = 'https://www.mediawiki.org/w/api.php'
params = {'action': 'query',
'titles': f'File:{d}',
'format': 'json',
'prop': 'imageinfo',
'iiprop': 'url'}
res = requests.get(url, params)
return res.json()['query']['pages']['-1']['imageinfo'][0]['url']
get_flag_url()
Ergebnis
'https://upload.wikimedia.org/wikipedia/commons/a/ae/Flag_of_the_United_Kingdom.svg'
Ein Problem, das plötzlich erst am Ende nach HTTP-Kenntnissen fragt. Es ist ein wenig schwierig zu lösen, ohne die Anfrage und Antwort zu kennen. Wenn Sie nicht gut verstehen und es grob verstehen möchten, können Sie das Video hier verwenden. Wenn Sie etwas mehr wissen möchten, [MDN-Dokument](https: //) developer.mozilla.org/en/docs/Web/HTTP/Overview) kann hilfreich sein.
In diesem Problem können Sie die URL des Flag-Bildes aus der Antwort extrahieren, die zurückgegeben wird, wenn Sie eine GET-Anforderung mit Python usw. an die MediaWiki-API senden. Dazu müssen Sie jedoch ein spezielles Modul importieren.
Es scheint, dass Sie urllib.request verwenden können, wenn Sie sich nicht die Mühe machen möchten, externe Pakete zu installieren, aber ich habe mich für Anfragen entschieden, weil ich es in der Vergangenheit installiert hatte. Dies ist ein einfacherer Code, und ich habe ihn geschrieben, weil er weit verbreitet ist, einschließlich des Beispiels auf der Seite hier von MediaWiki. Ich denke es ist einfach.
Übrigens können die 7 Zeilen in der Mitte wie unten gezeigt in 2 Zeilen geschrieben werden. In diesem Fall wächst die URL jedoch zu horizontal, sodass es besser ist, die Zeilen wie oben beschrieben zu trennen.
url = f'https://www.mediawiki.org/w/api.php?action=query&titles=File:{d}&format=json&prop=imageinfo&iiprop=url'
res = requests.get(url)
Reguläre Ausdrücke sind ein Werkzeug, das nicht nur in der Sprachverarbeitung, sondern auch in der Webentwicklung verwendet wird. Dieses Kapitel behandelt jedoch eine breite Palette von Themen, und ich fand, dass es ein gutes Unterrichtsmaterial ist.
Wie oben erwähnt, habe ich es mit dem Ziel geschrieben, genauen und präzisen Code zu erstellen. Wenn Sie jedoch Fehler haben, kommentieren Sie diese bitte.
Recommended Posts