<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>Perls Of Wisdom</title>
	<atom:link href="http://www.perlsofwisdom.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.perlsofwisdom.net</link>
	<description></description>
	<pubDate>Sun, 17 May 2009 20:44:17 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Emacs String Functions</title>
		<link>http://www.perlsofwisdom.net/emacs-string-functions/</link>
		<comments>http://www.perlsofwisdom.net/emacs-string-functions/#comments</comments>
		<pubDate>Sun, 17 May 2009 20:44:17 +0000</pubDate>
		<dc:creator>Jared</dc:creator>
		
		<category><![CDATA[Emacs]]></category>

		<category><![CDATA[basic emacs]]></category>

		<category><![CDATA[emacs lisp]]></category>

		<category><![CDATA[string functions]]></category>

		<category><![CDATA[strings]]></category>

		<guid isPermaLink="false">http://www.perlsofwisdom.net/?p=3</guid>
		<description><![CDATA[I looked into translating each of the examples in the PLEAC and it would be a lot of work.  Instead I&#8217;ll do my own thing.  This post covers function for working with strings.
Please give feedback if you can think of any improvements.
Characters and Strings
Strings are a sequence of characters.  Unlike many languages [...]]]></description>
			<content:encoded><![CDATA[<p>I looked into translating each of the examples in the <a href="http://pleac.sourceforge.net/pleac_perl.html">PLEAC</a> and it would be a lot of work.  Instead I&#8217;ll do my own thing.  This post covers function for working with strings.</p>
<p>Please give feedback if you can think of any improvements.</p>
<h3>Characters and Strings</h3>
<p class="first">Strings are a sequence of characters.  Unlike many languages emacs lisp doesn&#8217;t differentiate between characters and integers.  Evaluating <code>?A</code> returns 65.  Therefore you don&#8217;t need an <em>ord</em> or <em>char</em> function.</p>
<p>To convert a character (or integer) into a string use <code>(string ...)</code>.</p>
<pre class="src">
(string 65)  <span style="color: #b22222;">;; </span><span style="color: #b22222;">"A" is the same as
</span>(string ?A)  <span style="color: #b22222;">;; </span><span style="color: #b22222;">this
</span>
(string 10)  <span style="color: #b22222;">;; </span><span style="color: #b22222;">these two are
</span>(string ?\n) <span style="color: #b22222;">;; </span><span style="color: #b22222;">also the same
</span></pre>
<p>To extract a character from a string use <code>(elt ...)</code>.</p>
<pre class="src">
(elt <span style="color: #bc8f8f;">"ABC"</span> 1) <span style="color: #b22222;">;; </span><span style="color: #b22222;">66 -> the ASCII value of B
</span></pre>
<h3>Slicing and Dicing Strings</h3>
<p class="first">The basic function for slicing and dicing strings is <code>(substring  ...)</code> You pass it the string and from and to indexes.  0 indicates the start of the string and negative indexes measure length from the end.</p>
<pre class="src">
(<span style="color: #a020f0;">defvar</span> <span style="color: #b8860b;">data</span> <span style="color: #bc8f8f;">"1234567890123456789012345678901234567890"</span>)

(substring data 0 4)   <span style="color: #b22222;">;; </span><span style="color: #b22222;">1234
</span>(substring data 35)    <span style="color: #b22222;">;; </span><span style="color: #b22222;">67890
</span>(substring data 35 -1) <span style="color: #b22222;">;; </span><span style="color: #b22222;">6789
</span>(substring data -3 -1) <span style="color: #b22222;">;; </span><span style="color: #b22222;">89
</span></pre>
<p>To split a string use <code>(split-string ...)</code> defined in <em>subr.el</em>.</p>
<pre class="src">
(split-string <span style="color: #bc8f8f;">"a,b:c"</span> <span style="color: #bc8f8f;">"[,:]"</span>) <span style="color: #b22222;">;; </span><span style="color: #b22222;">("a" "b" "c")
</span></pre>
<p>You can join it back together with <code>(mapconcat ...)</code> which also takes a function with which you can transform each element.</p>
<pre class="src">
(mapconcat (<span style="color: #a020f0;">lambda</span> (e) e) '(<span style="color: #bc8f8f;">"abc"</span> <span style="color: #bc8f8f;">"def"</span> <span style="color: #bc8f8f;">"ghi"</span> <span style="color: #bc8f8f;">"klm"</span>) <span style="color: #bc8f8f;">","</span>)
<span style="color: #b22222;">;; </span><span style="color: #b22222;">gives --> "abc,def,ghi,klm"
</span></pre>
<p>Join strings together without a separator using <code>(concat ...)</code></p>
<pre class="src">
(concat <span style="color: #bc8f8f;">"Hello "</span> <span style="color: #bc8f8f;">"["</span> <span style="color: #bc8f8f;">"World"</span> <span style="color: #bc8f8f;">"] "</span> <span style="color: #bc8f8f;">"!!!"</span>) <span style="color: #b22222;">;; </span><span style="color: #b22222;">"Hello [World] !!!"
</span></pre>
<p>Convert strings to uppercase using <code>(upcase ...)</code>.  There are also <em>capitalize</em>, <em>downcase</em> and <em>upcase-initials</em>.</p>
<pre class="src">
(upcase <span style="color: #bc8f8f;">"abc"</span>) <span style="color: #b22222;">;; </span><span style="color: #b22222;">"ABC"
</span>(capitalize <span style="color: #bc8f8f;">"abc def"</span>) <span style="color: #b22222;">;; </span><span style="color: #b22222;">"Abc Def"
</span></pre>
<h3>Strings and Regular Expressions</h3>
<p class="first">The PLEAC has a nice example of substituting variables within a string using regular expressions.</p>
<pre class="src">
$AGE = 17;
$text = <span style="color: #bc8f8f;">'I am $AGE years old'</span>; <span style="color: #b22222;"># </span><span style="color: #b22222;">note single quotes
</span>$text =~ <span style="color: #66cd00;">s</span><span style="color: #5f9ea0;">/</span><span style="color: #a020f0;">(</span><span style="color: #da70d6;">\</span><span style="color: #bc8f8f;">$</span><span style="color: #da70d6;">\</span><span style="color: #228b22;">w</span><span style="color: #da70d6;">+</span><span style="color: #a020f0;">)</span><span style="color: #5f9ea0;">/</span>$1<span style="color: #5f9ea0;">/</span><span style="color: #66cd00;">eeg</span>;     <span style="color: #b22222;"># </span><span style="color: #b22222;">finds my() variables
</span></pre>
<p>Here is an imperfect translation into emacs-lisp.</p>
<pre class="src">
(<span style="color: #a020f0;">defvar</span> <span style="color: #b8860b;">AGE</span> 17)
(<span style="color: #a020f0;">defvar</span> <span style="color: #b8860b;">text</span> <span style="color: #bc8f8f;">"I am $AGE years old"</span>)

(<span style="color: #a020f0;">when</span> (string-match <span style="color: #bc8f8f;">"$</span><span style="color: #bc8f8f; font-weight: bold;">\\</span><span style="color: #bc8f8f; font-weight: bold;">(</span><span style="color: #bc8f8f;">[A-Z]+</span><span style="color: #bc8f8f; font-weight: bold;">\\</span><span style="color: #bc8f8f; font-weight: bold;">)</span><span style="color: #bc8f8f;">"</span> text)
  (concat (substring text 0 (match-beginning 0))
          (format <span style="color: #bc8f8f;">"%s"</span> (symbol-value (intern (match-string 1 text))))
          (substring text (match-end 0))))
</pre>
<h3>Unpack</h3>
<p><em>Bindat</em> is a library that provides similar to functionality to <em>pack</em> and <em>unpack</em> in perl.  This is the example given.</p>
<pre class="src">
<span style="color: #b22222;"># </span><span style="color: #b22222;">get a 5-byte string, skip 3, then grab 2 8-byte strings, then the rest
</span>($leading, $s1, $s2, $trailing) =
    <span style="color: #228b22;">unpack</span>(<span style="color: #bc8f8f;">"A5 x3 A8 A8 A*"</span>, $data);
</pre>
<p>The obvious translation doesn&#8217;t quite work - there might be a minor bug-ette in the library.  This fails with an <em>args-out-of-range</em> error.</p>
<pre class="src">
(<span style="color: #a020f0;">require</span> '<span style="color: #5f9ea0;">bindat</span>)

(bindat-unpack '((leading str 5)
                 (fill 3)
                 (s1 str 8)
                 (s2 str 8)
                 (rest str (eval (- (length data) bindat-idx))))
               data)
</pre>
<p>Subtracting an extra one leaves one character off <em>rest</em> as expected.</p>
<pre class="src">
<span style="color: #b22222;">;; </span><span style="color: #b22222;">((rest . "567890123456789")
</span><span style="color: #b22222;">;;  </span><span style="color: #b22222;">(s2 . "78901234")
</span><span style="color: #b22222;">;;  </span><span style="color: #b22222;">(s1 . "90123456")
</span><span style="color: #b22222;">;;  </span><span style="color: #b22222;">(leading . "12345"))
</span></pre>
<p>Fortunately, I have a workaround that extends the source string with a dummy character and then takes 1 fewer characters.  (yes, it is pretty horrible).</p>
<pre class="src">
(bindat-unpack '((leading str 5)
                 (fill 3)
                 (s1 str 8)
                 (s2 str 8)
                 (rest str (eval (- (length data) bindat-idx 1))))
               (concat data <span style="color: #bc8f8f;">"x"</span>))
</pre>
<p>And the full equivalent would be something like this.  As the association list is built in reverse order we need to reverse the parameter list.</p>
<pre class="src">
(<span style="color: #a020f0;">multiple-value-bind</span> (rest s2 s1 leading)
    (mapcar (<span style="color: #a020f0;">lambda</span> (e) (cdr e))
            (bindat-unpack '((leading str 5)
                             (fill 3)
                             (s1 str 8)
                             (s2 str 8)
                             (rest str (eval (- (length data) bindat-idx 1))))
                           (concat data <span style="color: #bc8f8f;">"x"</span>)))
            (insert <span style="color: #bc8f8f;">"\n"</span>)
            (insert (format <span style="color: #bc8f8f;">"[%s] [%s] [%s] [%s]"</span> leading s1 s2 rest)))
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.perlsofwisdom.net/emacs-string-functions/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
