2012-03-19 8 views
9

में अलग-अलग लंबाई पैटर्न खोजने के लिए PATINDEX का उपयोग करके मैं उन्हें खोजने के लिए PATINDEX() का उपयोग करके कुछ वर्चर्स से बाहर निकलने के लिए देख रहा हूं। मैं प्रत्येक वर्कर स्ट्रिंग में जानता हूं, मुझे केवल पहली फ्लोट में दिलचस्पी है, लेकिन उनमें अलग-अलग लंबाई हो सकती है।टी-एसक्यूएल

उदा

'some text 456.09 other text' 
'even more text 98273.453 la la la' 

मैं सामान्य रूप से एक regex

"[0-9]+[.][0-9]+" 

के साथ इन से मेल खाते हैं लेकिन, मैं + ऑपरेटर, जो PATINDEX स्वीकार करता है के लिए एक समान नहीं मिल सकता है जाएगा। तो वे मिलान किया जा करने के लिए (क्रमशः) के साथ की आवश्यकता होगी:

'[0-9][0-9][0-9].[0-9][0-9]' and '[0-9][0-9][0-9][0-9][0-9].[0-9][0-9][0-9]' 

वहाँ किसी भी तरह से इन उदाहरण के दोनों मैच के लिए है एक ही मान्य PATINDEX पैटर्न के साथ varchars?

+1

आपको रेगेक्स के साथ जाने की आवश्यकता हो सकती है। http://msdn.microsoft.com/en-us/magazine/cc163473.aspx – Paparazzi

उत्तर

0

PATINDEX ऐसा करने के लिए पर्याप्त शक्तिशाली नहीं है। आपको नियमित अभिव्यक्तियों का उपयोग करना चाहिए।

एसक्यूएल सर्वर एसक्यूएल सर्वर 2005

+0

एसक्यूएल सर्वर 2005/08 में रेगेक्स समर्थन के लिए, अतिरिक्त मॉड्यूल स्थापित करना आवश्यक है (मुझे विश्वास है) - लेकिन मुझे ऐसा करने से बहुत अधिक पसंद है – Richard

+0

PATINDEX ऐसा करने के लिए पर्याप्त शक्तिशाली है। कृपया मेरी पोस्ट देखें। –

+0

@Mastros क्षमा करें, लेकिन यह नहीं है। यह संभव है कि आप 'PATINDEX' का उपयोग करके "पर्याप्त पर्याप्त" समाधान प्राप्त कर सकें, लेकिन आपको कोई समाधान नहीं मिल सकता है जो किसी भी इनपुट को संभालता है।सामान्य मामले में काम करने वाले समाधान का निर्माण करने के लिए आपको वैकल्पिक वर्णों (जैसे regexp का '? 'मिलान करने की क्षमता की आवश्यकता है। –

2

वाइल्डकार्ड।

SELECT PATINDEX('%[0-9]%[0-9].[0-9]%[0-9]%','some text 456.09 other text') 
SELECT PATINDEX('%[0-9]%[0-9].[0-9]%[0-9]%','even more text 98273.453 la la la') 
+1

विफल: PATINDEX चुनें ('% [0-9]% [0-9]। [0-9]% [0-9] % ',' कुछ पाठ 4.9 अन्य पाठ ') –

+0

असफल नहीं: PATINDEX चुनें ('% [0-9]%।% [0-9]% ',' कुछ पाठ 4.9 अन्य पाठ ') – Ben

+0

@ बेन, मैं' मुझे डर है कि यह काम नहीं करेगा क्योंकि स्ट्रिंग में कोई भी फ्लोट नंबर नहीं हो सकता है जिसमें मुझे रूचि नहीं है। उदाहरण के लिए 'नंबर 2 फिर टेक्स्ट 43.9 अन्य टेक्स्ट' जिसके लिए यह पैटर्न वापस आएगा: '2 फिर टेक्स्ट 43.9' – Richard

1

हाँ आप clr से जोड़ने के लिए रेगुलर एक्सप्रेशन से समर्थन प्राप्त करने की आवश्यकता के बाद से नियमित अभिव्यक्ति समर्थन हासिल है। लेकिन यदि पैटिंडेक्स आपको जो चाहिए वह नहीं करता है तो रेगेक्स को इसके लिए बिल्कुल डिजाइन किया गया था।

http://msdn.microsoft.com/en-us/magazine/cc163473.aspx

+0

ध्यान दें कि SQL सर्वर के बाद के संस्करण इस बाहरी पैकेज को बहाने पर इनकार करते हैं कि कोड शुद्ध .NET असेंबली नहीं है। [इस संबंधित प्रश्न देखें] (http://stackoverflow.com/q/15173120)। – Jerry

+0

@ जेरी आप [SQL #] (http://www.SQLsharp.com/) लाइब्रेरी को इंस्टॉल करके नियमित रूप से नियमित अभिव्यक्तियां प्राप्त कर सकते हैं (जिसे मैंने लिखा था, लेकिन RegEx सामग्री मुफ़्त संस्करण में है)। यह लाइब्रेरी SQL सर्वर 2005 से शुरू होने वाले SQL सर्वर के सभी संस्करणों में काम करती है। –

0

यह देखते हुए कि पैटर्न लंबाई में अलग किया जा रहा है, तो आप एक किसी न किसी समय इस रही PATINDEX के साथ काम करने के लिए नहीं जा रहे हैं। There is another post that I wrote, जिसे मैंने यहां पूरा करने की कोशिश कर रहे हैं, उसे पूरा करने के लिए संशोधित किया है। क्या यह आपके लिए काम करेगा?

CREATE TABLE #nums (n INT) 
DECLARE @i INT 
SET @i = 1 
WHILE @i < 8000 
BEGIN 
    INSERT #nums VALUES(@i) 
    SET @i = @i + 1 
END 

CREATE TABLE #tmp (
    id INT IDENTITY(1,1) not null, 
    words VARCHAR(MAX) null 
) 

INSERT INTO #tmp 
VALUES('I''m looking for a number, regardless of length, even 23.258 long'),('Maybe even pi which roughly 3.14159265358,'),('or possibly something else that isn''t a number') 

UPDATE #tmp SET words = REPLACE(words, ',',' ') 

;WITH CTE AS (SELECT ROW_NUMBER() OVER (ORDER BY ID) AS rownum, ID, NULLIF(SUBSTRING(' ' + words + ' ' , n , CHARINDEX(' ' , ' ' + words + ' ' , n) - n) , '') AS word 
    FROM #nums, #tmp 
    WHERE ID <= LEN(' ' + words + ' ') AND SUBSTRING(' ' + words + ' ' , n - 1, 1) = ' ' 
    AND CHARINDEX(' ' , ' ' + words + ' ' , n) - n > 0), 
    ids AS (SELECT ID, MIN(rownum) AS rownum FROM CTE WHERE ISNUMERIC(word) = 1 GROUP BY id) 
SELECT CTE.rownum, cte.id, cte.word 
FROM CTE, ids WHERE cte.id = ids.id AND cte.rownum = ids.rownum 

स्पष्टीकरण और कोड के मूल origional post

1

में अधिक विस्तार से कवर किया जाता है मजबूती (यदि आप केवल एक पूर्णांक है क्या उदाहरण के लिए,) के लिए जाँच की जानी चाहिए, लेकिन यह सिर्फ डाल करने के लिए है एक ट्रैक पर:

if exists (select routine_name from information_schema.routines where routine_name = 'GetFirstFloat') 
    drop function GetFirstFloat 
go 

create function GetFirstFloat (@string varchar(max)) 
returns float 
as 
begin 
    declare @float varchar(max) 
    declare @pos int 

    select @pos = patindex('%[0-9]%', @string) 
    select @float = '' 

    while isnumeric(substring(@string, @pos, 1)) = 1 
    begin 
     select @float = @float + substring(@string, @pos, 1) 
     select @pos = @pos + 1 
    end 

    return cast(@float as float) 
end 
go 


select dbo.GetFirstFloat('this is a string containing pi 3.14159216 and another non float 3 followed by a new fload 5.41 and that''s it') 
select dbo.GetFirstFloat('this is a string with no float') 
select dbo.GetFirstFloat('this is another string with an int 3') 
+0

यह लूप के बिना किया जा सकता है। मेरी पोस्ट देखें –

+0

पूर्णांक के लिए एक आकर्षण की तरह बहुत स्पष्ट और काम किया! धन्यवाद। – Yosoyadri

12

मैंने कुछ समय पहले इस बारे में भी ब्लॉग। Extracting numbers with SQL server

Declare @Temp Table(Data VarChar(100)) 

Insert Into @Temp Values('some text 456.09 other text') 
Insert Into @Temp Values('even more text 98273.453 la la la') 
Insert Into @Temp Values('There are no numbers in this one') 

Select Left(
      SubString(Data, PatIndex('%[0-9.-]%', Data), 8000), 
      PatIndex('%[^0-9.-]%', SubString(Data, PatIndex('%[0-9.-]%', Data), 8000) + 'X')-1) 
From @Temp 
+0

काम नहीं करेगा यदि आपके पास स्ट्रिंग में दो फ्लोट हैं, है ना? –

+1

वह अभिव्यक्ति ** ** ** से मेल खाती है, जो शायद ही कभी एक फ्लोट है। –

+0

शानदार! वास्तव में जो मैं खोज रहा था, धन्यवाद !!!! –

संबंधित मुद्दे