2011-08-24 20 views
5

हास्केल string literals कि \ भागने अनुक्रम का उपयोग की एक संख्या है। लोगों को इस तरह के \n, \t, \NUL के रूप में।हास्केल: " 0" " 0" में कैसे प्राप्त करें?

अगर मैं स्ट्रिंग शाब्दिक है:

let s = "Newline: \\n Tab: \\t" 

मैं समारोह escape :: String -> String कि करने के लिए ऊपर स्ट्रिंग में परिवर्तित कर देंगे कैसे परिभाषित करते हैं:

"Newline: \n Tab: \t" 

और सभी अन्य स्ट्रिंग शाब्दिक भागने दृश्यों के साथ एक ही ।

मैं अर्ध का हवाला देते हुए और खाका हास्केल उपयोग करने के साथ ठीक हूँ, लेकिन कैसे परिणाम प्राप्त करने के लिए उन्हें का उपयोग करने के पता नहीं है। कोई संकेतक?


अद्यतन: मैं बस Text.ParserCombinators.ReadP मॉड्यूल है कि बेस पुस्तकालय में शामिल है मिल गया। यह होता है कि जो मैं चाहता Data.Char में readLitChar :: ReadS Char समारोह का समर्थन करता है, लेकिन मैं कैसे ReadP मॉड्यूल का उपयोग करने के लिए पता नहीं है। मैंने निम्नलिखित की कोशिश की और यह काम करता है:

escape2 [] = [] 
escape2 xs = case readLitChar xs of 
    [] -> [] 
    [(a, b)] -> a : escape2 b 

लेकिन यह रीडपी मॉड्यूल का उपयोग करने का सही तरीका नहीं हो सकता है। क्या कोई कुछ पॉइंटर्स प्रदान कर सकता है?

कोई अन्य अपडेट: सभी को धन्यवाद। नीचे मेरा अंतिम कार्य। बुरा नहीं, मुझे लगता है।

import Text.ParserCombinators.ReadP 
import Text.Read.Lex 

escape xs 
    | []  <- r = [] 
    | [(a,_)] <- r = a 
    where r = readP_to_S (manyTill lexChar eof) xs 
+0

हो सकता है आप इस्तेमाल कर सकते हैं Haskell-src (http://hackage.haskell.org/ पैकेज/हैकेल-src) लेकिन शायद यह अधिक है ... अद्यतन: शायद (पढ़ें ("\" "++ s ++" \ "")) :: स्ट्रिंग –

उत्तर

6

आपको कुछ भी करने की आवश्यकता नहीं है। जब आप स्ट्रिंग शाब्दिक इनपुट

let s = "Newline: \\n Tab: \\t" 

आप जाँच कर सकते हैं यह है कि यह आप क्या चाहते हैं:

Prelude> putStrLn s 
Newline: \n Tab: \t 
Prelude> length s 
19 

तुम सिर्फ तुम कुछ और मिल जाएगा s के मूल्य के लिए GHCi कहते हैं, तो

Prelude> s 
"Newline: \\n Tab: \\t" 

स्पष्ट रूप से यह आपकी पीठ के पीछे कुछ भागने का स्वरूपण कर रहा है, और यह उद्धरण भी प्रदर्शित करता है। आप show फोन या print यदि आप अभी तक अन्य उत्तर मिल जाएगा:

Prelude> show s 
"\"Newline: \\\\n Tab: \\\\t\"" 
Prelude> print s 
"Newline: \\n Tab: \\t" 

इसका कारण यह है show मूल्यों serializing के लिए है, इसलिए जब आप show एक स्ट्रिंग आप मूल वापस नहीं मिलता है, आप के बजाय एक मिल serialized स्ट्रिंग जिसे मूल स्ट्रिंग में पार्स किया जा सकता है। show s का परिणाम वास्तव में print s द्वारा प्रदर्शित किया गया है (print को putStrLn . show के रूप में परिभाषित किया गया है)। जब आप ghci में show s पर एक अजनबी उत्तर मिलता है; यहाँ GHCi वर्ण जो show से क्रमानुसार लगे हुए हैं स्वरूपण है।

टीएल; डॉ - हमेशा स्ट्रिंग का मूल्य ghci में क्या है यह देखने के लिए putStrLn का उपयोग करें।

संपादित: मैं बस महसूस किया कि हो सकता है आप वास्तविक नियंत्रण दृश्यों में शाब्दिक मूल्य

Newline: \n Tab: \t 

परिवर्तित करना चाहते हैं।

Prelude> let s' = '"' : s ++ "\"" 
Prelude> read s' :: String 
"Newline: \n Tab: \t" 
Prelude> putStrLn (read s') 
Newline: 
Tab: 

संपादित 2:

strParser :: ReadP String 
strParser = do 
    str <- many (readS_to_P readLitChar) 
    eof 
    return str 
: readLitChar उपयोग का एक उदाहरण है, इस readLitChar साथ छोड़कर क्रिस जवाब देने के लिए बहुत करीब है यह करने के लिए सबसे आसान तरीका शायद उद्धरण में यह छड़ी और प्रयोग read है

फिर आप इसे readP_to_S के साथ चलाते हैं, जो आपको मिलान करने वाले पार्स की एक सूची देता है (एक से अधिक मैच नहीं होने चाहिए, हालांकि कोई मिलान नहीं हो सकता है, इसलिए आपको खाली सूची की जांच करनी चाहिए।)

> putStrLn . fst . head $ readP_to_S strParser s 
Newline: 
Tab:  
> 
+0

स्ट्रिंग के चारों ओर उद्धरणों का एक सेट जोड़ रहा है और कर रहा है एक विश्वसनीय विश्वसनीय? – Snoqual

+0

@Snoqual: पूरी तरह से नहीं। एक एम्बेडेड उद्धरण के साथ एक स्ट्रिंग पर विचार करें: '" \ "" '। 'पढ़ना' इस मामले में एक पार्स त्रुटि फेंक देगा। आप या तो उद्धरण वर्णों में भाग ले सकते हैं (मैं विभाजन पैकेज का उपयोग करता हूं), या, क्योंकि आप स्ट्रिंग अक्षर का उपयोग करके, परीक्षण करें कि यह प्रत्येक स्ट्रिंग के साथ काम करता है। –

2

क्यू क्यू और टीएच के बारे में पूछने का मतलब है कि आप संकलन समय पर यह रूपांतरण करना चाहते हैं। सरल स्ट्रिंग के लिए -> कुछ रूपांतरण आप जीएचसी में OverloadedString शाब्दिक सुविधा का उपयोग कर सकते हैं।

संपादित 2: Text.Read.Lex में उजागर चरित्र lexer का उपयोग

module UnEscape where 

import Data.String(IsString(fromString)) 
import Text.ParserCombinators.ReadP as P 
import Text.Read.Lex as L 

newtype UnEscape = UnEscape { unEscape :: String } 

instance IsString UnEscape where 
    fromString rawString = UnEscape lexed 
    where lexer = do s <- P.many L.lexChar 
        eof 
        return s 
      lexed = case P.readP_to_S lexer rawString of 
        ((answer,""):_) -> answer 
        _ -> error ("UnEscape could not process "++show rawString) 

संपादित करें 1:

instance IsString UnEscape where 
    fromString rawString = UnEscape (read (quote rawString)) 
    where quote s = '"' : s ++ ['"'] 
: मैं अब एक बेहतर unescape उदाहरण GHC के पढ़ने का उपयोग करता है मिल गया है

उदाहरण के लिए:

module UnEscape where 

import Data.String(IsString(fromString)) 

newtype UnEscape = UnEscape { unEscape :: String } 

instance IsString UnEscape where 
    fromString rawString = UnEscape (transform rawString) 
    where transform [] = [] 
      transform ('\\':x:rest) = replace x : transform rest 
      transform (y:rest) = y : transform rest 
      -- also covers special case of backslash at end 
      replace x = case x of 
         'n' -> '\n' 
         't' -> '\t' 
         unrecognized -> unrecognized 
,210

ऊपर मॉड्यूल unescape का उपयोग करता है से एक अलग मॉड्यूल हो गया है:

{-# LANGUAGE OverloadedStrings #-} 
module Main where 

import UnEscape(UnEscape(unEscape)) 

main = do 
    let s = "Newline: \\n Tab: \\t" 
     t = unEscape "Newline: \\n Tab: \\t" 
    print s 
    putStrLn s 
    print t 
    putStrLn t 

यह पैदा करता है

shell prompt$ ghci Main.hs 


GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help 
Loading package ghc-prim ... linking ... done. 
Loading package integer-gmp ... linking ... done. 
Loading package base ... linking ... done. 
Loading package ffi-1.0 ... linking ... done. 
[1 of 2] Compiling UnEscape   (UnEscape.hs, interpreted) 
[2 of 2] Compiling Main    (Main.hs, interpreted) 
Ok, modules loaded: Main, UnEscape. 
*Main> main 
"Newline: \\n Tab: \\t" 
Newline: \n Tab: \t 
"Newline: \n Tab: \t" 
Newline: 
Tab: 
+0

हाय क्रिस। धन्यवाद। मुझे उम्मीद थी कि मुझे अपने कोड में सभी भागने के दृश्यों की पूरी पार्सिंग क्षमता को पुन: पेश नहीं करना पड़ेगा। – Snoqual

+0

मुझे जल्दी से सरल नहीं मिल रहा है जगह जहां जीएचसी अपने आंतरिक पार्सिंग फ़ंक्शन का खुलासा करता है। लेकिन आप इसे जीएचसी में पा सकते हैं और इसे कॉपी/पेस्ट कर सकते हैं। –

+0

मेरा मतलब यह है कि मैं या तो खुद को लागू करने या प्रतिलिपि बनाकर उस क्षमता को दोहराना नहीं चाहता हूं। मैं एक का उपयोग करना चाहता हूं अंतर्निर्मित क्षमता का खुला संस्करण। – Snoqual

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