2012-12-05 17 views
5

Podaję tę odpowiedź, ale chciałem rozwinąć pytanie i nie mogłem znaleźć żadnych rozwiązań tutaj na stosie lub poprzez wyszukiwanie google.Parsować domenę z podanego adresu URL w T-SQL

Substring domainname from URL SQL

Zasadniczo link powyżej rozwiązuje mój problem z prostym jak parsowania URL "www.google.com" z wynikiem google.

To, czego szukam, aby rozwinąć to rozwiązanie z powyższego linku, nie pomaga w adresach URL takich jak "www.maps.google.com", które po prostu zwracają mapy.

Chciałbym, aby zwrócił "google" z adresu URL "www.maps.google.com" lub zwrócił "przykład" z "www.test.example.com".

Jeśli ktoś ma rozwiązanie tego, byłbym bardzo wdzięczny.

Aktualizacja: Aby być bardziej konkretny będę również muszą parsowania na domena drugiego poziomu itd. „Www.maps.google.com.au” powrót „google”

Oto moja funkcja SQL.

CREATE FUNCTION [dbo].[parseURL] (@strURL varchar(1000)) 
RETURNS varchar(1000) 
AS 
BEGIN 

IF CHARINDEX('.', REPLACE(@strURL, 'www.','')) > 0 
SELECT @strURL = LEFT(REPLACE(@strURL, 'www.',''), CHARINDEX('.',REPLACE(@strURL,    'www.',''))-1) 
Else 
SELECT @strURL = REPLACE(@strURL, 'www.','') 

RETURN @strURL 
END 
+1

Jak chcesz zajmować się [domenami drugiego poziomu] (http://en.wikipedia.org/wiki/Second-level_domain), np. 'www.google.com.sg' lub' bbc.co.uk'? – ig0774

+0

Tak, właśnie zaktualizowałem moje pytanie, aby uwzględnić domeny drugiego poziomu. Chciałbym też zwrócić "google" z "www.google.com.sg". –

Odpowiedz

6

sugeruję ten

DECLARE @URL nvarchar(max) = 'www.maps.google.com' 

DECLARE @X xml = CONVERT(xml,'<root><part>' + REPLACE(@URL, '.','</part><part>') + '</part></root>') 

SELECT [Domain] = T.c.value('.','varchar(20)') 
FROM @X.nodes('/root/part[position() = last() - 1]') T(c) 

Podejście jest konwersja URL do pliku XML, a następnie użyć XPath aby znaleźć domenę.

UPDATE

chodzi domen drugiego poziomu, wierzę jedyny niezawodny sposób go mieć je wszystkie w tabeli (domeny najwyższego poziomu prawdopodobnie powinien być w tabeli zbyt), a następnie można użyć tego zapytanie:

DECLARE @URL nvarchar(max) = 'www.maps.google.com' 

DECLARE @X xml = CONVERT(xml,'<root><part>' + REPLACE(REVERSE(@URL), '.','</part><part>') + '</part></root>') 

;WITH SplitCTE AS 
(
    SELECT 
     (SELECT REVERSE(T.c.value('.', 'nvarchar(256)')) FROM @X.nodes('/root/part[. = ../part[position() = 1]]') T(c)) AS TLD, 
     (SELECT REVERSE(T.c.value('.', 'nvarchar(256)')) FROM @X.nodes('/root/part[. = ../part[position() = 2]]') T(c)) AS D2, 
     (SELECT REVERSE(T.c.value('.', 'nvarchar(256)')) FROM @X.nodes('/root/part[. = ../part[position() = 3]]') T(c)) AS D3 
) 
SELECT 
    CASE 
     WHEN SLD.Domain IS NULL THEN S.D2 ELSE S.D3 
    END AS Domain 
FROM 
    SplitCTE AS S 
    LEFT JOIN TLD ON TLD.Domain = S.TLD 
    LEFT JOIN SLD ON SLD.Domain = S.D2 

Tabele TLD/SLD, których użyłem w tym przykładzie, znajdują się poniżej. Pełna lista domen znajduje się w tym wiki. Zachowaj ostrożność, używając NVARCHAR, ponieważ niektóre są zlokalizowane.

CREATE TABLE dbo.TLD 
(
    Domain nvarchar(10) 
) 
GO 

CREATE TABLE dbo.SLD 
(
    Domain nvarchar(10) 
) 
GO 

INSERT TLD VALUES ('com') 
INSERT TLD VALUES ('uk') 
INSERT SLD VALUES ('co') 
+0

To właśnie musiałem zrobić. Mam wszystkie TLD w jednej tabeli, a następnie skompilowałem listę domen drugiego poziomu i umieściłem to w tabeli i użyłem twojego zapytania powyżej. Ból znajduje listę domen drugiego poziomu. Dziękuję za odpowiedź i pomoc w tej sprawie. –

3

Ktoś będzie prawdopodobnie mieć lepsze rozwiązanie, ale tutaj jest to, co mam:

LEFT(RIGHT(@strURL, CHARINDEX('.', REVERSE(@strURL)) + CHARINDEX('.', SUBSTRING(REVERSE(@strURL), CHARINDEX('.', REVERSE(@strURL)) + 1, LEN(@strURL))) - 1), CHARINDEX('.', SUBSTRING(REVERSE(@strURL), CHARINDEX('.', REVERSE(@strURL)) + 1, LEN(@strURL))) - 1) 

nie jestem najlepszy w ciąg manipulacji, więc jestem pewien, że to jest możliwe, aby skrócić mój bardzo długą linię kodu. Zasadniczo użyłbym funkcji REVERSE, aby uzyskać ostatni okres, a następnie przejść od tego miejsca. Mój kod wprowadza znaki między ostatnim a drugim na końcu przecinkiem.

Należy pamiętać, że korzystanie z witryny internetowej, takiej jak www.test.co.uk, nie będzie działać z moim rozwiązaniem. Chciałbym zaproponować, że jest to tylko punkt wyjścia, a musielibyśmy kodować dla wartości odstających.

+0

To działa świetnie na coś, co ma tylko jedno rozszerzenie. Co, jeśli i ja powinienem być bardziej konkretny w moim pytaniu, powiedzmy, że URL to "www.maps.google.com.au". Twoja odpowiedź zwraca "com". Poza tym ta odpowiedź zadziałała świetnie i dziękuję za odpowiedź. –

+0

Masz absolutną rację. Problemem, który będziesz miał, są wszystkie możliwe wartości odstające. Poleciłbym coś podobnego do tego, co sugeruje Serge, i umieścił stany odstające w tabeli, aby się do nich odniosły. My jako ludzie możemy łatwo zidentyfikować potrzebne dane, ale niestety komputer nie może tego zrobić. To naprawdę zależy od tego, jak dokładna jest twoja potrzeba. Ponadto, jeśli chodzi o skalowalność, chciałbym ponownie zasugerować próbę zrozumienia, co robi Serge w swoim poście. Moja metoda jest szybka i brudna, ale jeśli potrzebujesz dodać więcej logiki, prawdopodobnie nie jest to najlepsza trasa. – Neil

2

PARSENAME podzieli się na cztery części oddzielone znakami "." znak. Parsename liczy się od prawej. Jeśli nazwa_obiektu do przeanalizowania ma więcej niż cztery części, NULL zostanie ponownie wywołana.

select PARSENAME (REPLACE('www.maps.google.com.au', 'www.','') , 3) 
select PARSENAME (REPLACE('www.maps.google.com', 'www.','') , 2) 
+0

działa to w niektórych przypadkach, ale nie na poziomie, którego potrzebuję, dziękuję za odpowiedź. –

4

Problem związany z domeną TLD może znacznie spowolnić Twój kod i dodać wymaganie dotyczące obsługi, dlatego zdecydowałem się dołączyć subdomeny.Oto, czego używam:

ALTER FUNCTION dbo.spExtractDomainFromURL (@strURL NVARCHAR(1000)) 
RETURNS NVARCHAR(100) 
AS 
BEGIN 
    --Strip Protocol 
    SELECT @strURL = SUBSTRING(@strURL, CHARINDEX('://', @strURL) + 3, 999) 

    -- Strip www subdomain 
    IF LEFT(@strURL, 4) = 'www.' 
     SELECT @strURL = SUBSTRING(@strURL, 5, 999) 

    -- Strip Path 
    IF CHARINDEX('/', @strURL) > 0 
     SELECT @strURL = LEFT(@strURL, CHARINDEX('/', @strURL) - 1) 

    RETURN @strURL 
END 
2

co zrobiłem tutaj jest podciąg url po protokole „: //”.

Następnie biorę ten ciąg i podciągam cały tekst do pierwszego ukośnika w przód.

Możesz to zrobić również w jednym wierszu, jeśli potrzebujesz go do zapytania lub użyć go jako funkcji skalarnej, tak jak ja.

Warto również dodać kod, aby sprawdzić wartości zerowe lub ogólnie złe ciągi. Jeśli chcesz zachować go jako pojedynczą linię kodu, spróbuj użyć funkcji ISNULL i NULLIF.

DECLARE @urlSansProtocol VARCHAR(MAX) 
SET @urlSansProtocol = Substring(@url, CharIndex('://', @url)+3 ,LEN(@url)) 
RETURN Substring(@urlSansProtocol, 0 ,CharIndex('/', @urlSansProtocol)) 
+2

Powinieneś dołączyć kilka wyjaśnień. –

Powiązane problemy