Bei der Rails-Mail-Verarbeitung wollte ich manchmal die in der Zeichenfolge enthaltene URL in ein a-Tag konvertieren.
Nach ein wenig Recherche können Sie die URL der Zeichenfolge mithilfe von "URI.extract" leicht ermitteln. .. .. Ich dachte, es wäre relativ einfach zu schreiben, aber tatsächlich gab es einige Fallen und ich blieb stecken, also beschloss ich, es zu schreiben, nachdem ich es überprüft hatte.
TL;DR Der endgültige Code wurde wie folgt gelöst. Wie bist du dazu gekommen? Ich werde später erklären, warum das gut ist.
def convert_url_to_a_element(text)
uri_reg = URI.regexp(%w[http https])
text.gsub(uri_reg) { %{<a href='#{$&}' target='_blank'>#{$&}</a>} }
end
text = 'url1: http://hogehoge.com/hoge url2: http://hogehoge.com/fuga'
convert_url_to_a_element(text)
=> "url1: <a href='http://hogehoge.com/hoge' target='_blank'>http://hogehoge.com/hoge</a> url2: <a href='http://hogehoge.com/fuga' target='_blank'>http://hogehoge.com/fuga</a>"
Zunächst einmal, wie man den falschen Prozess schreibt. Trotzdem kann der folgende Text problemlos verarbeitet werden. Deshalb habe ich diese Schreibfalle diesmal nicht sofort bemerkt. .. ..
def convert_url_to_a_element(text)
URI.extract(text, %w[http https]).uniq.each do |url|
sub_text = "<a href='#{url}' target='_blank'>#{url}</a>"
text.gsub(url, sub_text)
end
text
end
text = 'url1: http://hogehoge.com url2: http://fugafuga.com'
convert_url_to_a_element(text)
=> 'url1: http://hogehoge.com url2: http://fugafuga.com'
Wenn Sie "URI.extract" verwenden, können Sie alle Zeichenfolgen im URL-Format abrufen, wie unten gezeigt.
text = 'url1: http://hogehoge.com url2: http://fugafuga.com'
URI.extract(text, %w[http https])
=> ["http://hogehoge.com", "http://fugafuga.com"]
Dies wird durch Drehen ersetzt. Wenn es jedoch mit zwei Arten von URLs mit demselben Domainnamen wie unten gezeigt implementiert ist. .. ..
text = 'url1: http://hogehoge.com/hoge url2: http://hogehoge.com'
convert_url_to_a_element(text)
=> "url1: <a href='<a href='http://hogehoge.com' target='_blank'>http://hogehoge.com</a>/hoge' target='_blank'><a href='http://hogehoge.com' target='_blank'>http://hogehoge.com</a>/hoge</a> url2: <a href='http://hogehoge.com' target='_blank'>http://hogehoge.com</a>"
Irgendwie ist es wirklich zusammengebrochen. .. ..
Die Ursache ist, dass der Text nach einer Tag-Konvertierung auch beim zweiten Ersetzen ersetzt wurde. Wie Sie sehen können, gibt es eine Gefahr, dass ** es nicht gut funktioniert, wenn zwei oder mehr URLs mit demselben Hostnamen ** in der obigen Schreibmethode vorhanden sind.
Sie können eine doppelte Ersetzung verhindern, indem Sie den regulären Ausdruck abrufen und durch den regulären Ausdruck im gsub-Muster ersetzen, anstatt die durch "URI.extract" erhaltene Zeichenfolge mit jedem zu drehen.
def convert_url_to_a_element(text)
uri_reg = URI.regexp(%w[http https])
text.gsub(uri_reg) { %{<a href='#{$&}' target='_blank'>#{$&}</a>} }
end
URI.regexp
ist eine Methode, die das Muster der URL-Zeichenfolge des angegebenen Schemas als regulären Ausdruck zurückgibt. Da ein regulärer Ausdruck eine Zeichenfolge ist, können Sie ihn selbst schreiben, aber diese Methode erstellt ihn schnell.
Wie Sie dem Rückgabewert entnehmen können, hatte ich keine Lust, dies von Grund auf neu zu schreiben. .. ..
URI.regexp(%w[http https])
=> /(?=(?-mix:http|https):)
([a-zA-Z][\-+.a-zA-Z\d]*): (?# 1: scheme)
(?:
((?:[\-_.!~*'()a-zA-Z\d;?:@&=+$,]|%[a-fA-F\d]{2})(?:[\-_.!~*'()a-zA-Z\d;\/?:@&=+$,\[\]]|%[a-fA-F\d]{2})*) (?# 2: opaque)
|
(?:(?:
\/\/(?:
(?:(?:((?:[\-_.!~*'()a-zA-Z\d;:&=+$,]|%[a-fA-F\d]{2})*)@)? (?# 3: userinfo)
(?:((?:(?:[a-zA-Z0-9\-.]|%\h\h)+|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[(?:(?:[a-fA-F\d]{1,4}:)*(?:[a-fA-F\d]{1,4}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|(?:(?:[a-fA-F\d]{1,4}:)*[a-fA-F\d]{1,4})?::(?:(?:[a-fA-F\d]{1,4}:)*(?:[a-fA-F\d]{1,4}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))?)\]))(?::(\d*))?))? (?# 4: host, 5: port)
|
((?:[\-_.!~*'()a-zA-Z\d$,;:@&=+]|%[a-fA-F\d]{2})+) (?# 6: registry)
)
|
(?!\/\/)) (?# XXX: '\/\/' is the mark for hostport)
(\/(?:[\-_.!~*'()a-zA-Z\d:@&=+$,]|%[a-fA-F\d]{2})*(?:;(?:[\-_.!~*'()a-zA-Z\d:@&=+$,]|%[a-fA-F\d]{2})*)*(?:\/(?:[\-_.!~*'()a-zA-Z\d:@&=+$,]|%[a-fA-F\d]{2})*(?:;(?:[\-_.!~*'()a-zA-Z\d:@&=+$,]|%[a-fA-F\d]{2})*)*)*)? (?# 7: path)
)(?:\?((?:[\-_.!~*'()a-zA-Z\d;\/?:@&=+$,\[\]]|%[a-fA-F\d]{2})*))? (?# 8: query)
)
(?:\#((?:[\-_.!~*'()a-zA-Z\d;\/?:@&=+$,\[\]]|%[a-fA-F\d]{2})*))? (?# 9: fragment)
/x
Die gsub-Methode selbst kann durch Übergeben einer Zeichenfolge anstelle eines regulären Ausdrucks ersetzt werden. Im ersteren Fall wird die erfasste URL-Zeichenfolge einfach von jeder übergeben und ersetzt. Wenn die URL jedoch dieselbe Domäne enthält, wird die Zeichenfolge nach einer Tag-Konvertierung ebenfalls ersetzt. Scheint ausgeführt zu werden, was zu einer seltsamen Zeichenkette führt.
Wenn Sie darüber nachdenken, ist das richtig. .. .. Ich war besorgt, weil mir diese Maßnahme nicht einfiel. Zunächst einmal gsub
text.gsub!(uri_reg) { %{<a href="#{$&}">#{$&}</a>} }
Zunächst wird zuerst "URI.extract" verwendet, aber Sie können nur die URL-Zeichenfolge aus dem Text abrufen, indem Sie das Schema angeben. Ich habe es diesmal nicht benutzt, aber es schien nützlich zu sein, wenn ich nur die URL-Zeichenfolge einfach erhalten wollte.
text = 'aaaaa http://xxx.com/hoge bbbbb http://xxx.com'
URI.extract(text, %w[http https])
=> ["http://xxx.com/hoge" "http://xxx.com"]
Es gab Drehungen und Wendungen, aber ich denke, es war ein guter Code. Wenn Sie einen anderen guten Schreibstil haben, lassen Sie es mich bitte wissen.
Recommended Posts