* help with regexp function
@ 2017-11-21 23:30 B. T. Raven
2017-11-22 11:15 ` Stephen Berman
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: B. T. Raven @ 2017-11-21 23:30 UTC (permalink / raw)
To: help-gnu-emacs
Dear Emacs gurus:
I can perform this inteactive substitution
CM-%: \(^[0-9]+ \)\(.+\) -> \2 \1)
in order to change a buffer line prefixed with a number into one
post-fixed with the same number but I can't figue out how to do the same
programatically to a whole region. I started with this code:
(defun verse-num-move-beg-to-end (beg end)
"Move int-string and following space from beginning of line to end of
line throughout region."
(interactive "r")
(goto-char beg)
(while (<= (point) end)
(re-search-forward "^[0-9]+ ")
(setq num (substring (match-string 0) 0 -1)) ;; should be a string
of ;;digits without trailing space
(print num)
;; here the value generates a wrong argument error:
setq: Wrong type argument: listp, #("234" 0 3 (fontified t))
(type-of #("234" 0 3 (fontified t)))
;; I have a function which is a black box to to me but it works in the
larger context I have it in. Does match-string do something like this
implicitly (casting a list as a string?)
...
(substring (match-string 0) 0 -1)
(replace-match "" nil t)
234 asentuhasneothu ;; example buffer-line
Any help apppreciated.
Ed
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: help with regexp function
2017-11-21 23:30 help with regexp function B. T. Raven
@ 2017-11-22 11:15 ` Stephen Berman
2017-11-22 17:05 ` Kendall Shaw
[not found] ` <mailman.4298.1511349362.27995.help-gnu-emacs@gnu.org>
2 siblings, 0 replies; 7+ messages in thread
From: Stephen Berman @ 2017-11-22 11:15 UTC (permalink / raw)
To: B. T. Raven; +Cc: help-gnu-emacs
On Tue, 21 Nov 2017 17:30:15 -0600 "B. T. Raven" <btraven@nihilo.net> wrote:
> Dear Emacs gurus:
>
> I can perform this inteactive substitution
> CM-%: \(^[0-9]+ \)\(.+\) -> \2 \1)
> in order to change a buffer line prefixed with a number into one post-fixed
> with the same number but I can't figue out how to do the same programatically
> to a whole region. I started with this code:
>
> (defun verse-num-move-beg-to-end (beg end)
> "Move int-string and following space from beginning of line to end of line
> throughout region."
> (interactive "r")
> (goto-char beg)
> (while (<= (point) end)
> (re-search-forward "^[0-9]+ ")
> (setq num (substring (match-string 0) 0 -1)) ;; should be a string of
> ;;digits without trailing space
> (print num)
Here's a pretty direct translation of the interactive substitution:
(defun verse-num-move-beg-to-end (beg end)
"Move int-string and following space from beginning of line to
end of line throughout region."
(interactive "r")
(goto-char beg)
(while (<= (point) end)
(re-search-forward "^\\([0-9]+\\) \\(.*\\)$")
(replace-match (concat (match-string 2) " " (match-string 1) ")"))))
> ;; here the value generates a wrong argument error:
> setq: Wrong type argument: listp, #("234" 0 3 (fontified t))
> (type-of #("234" 0 3 (fontified t)))
I can't tell what the problem without seeing the code that causes it.
Were you trying to treat the propertized string as a list because of the
#(...) notation?
> ;; I have a function which is a black box to to me but it works in the larger
> context I have it in. Does match-string do something like this implicitly
> (casting a list as a string?)
Not AFAIK.
> (substring (match-string 0) 0 -1)
> (replace-match "" nil t)
>
>
> 234 asentuhasneothu ;; example buffer-line
>
> Any help apppreciated.
>
> Ed
Steve Berman
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: help with regexp function
2017-11-21 23:30 help with regexp function B. T. Raven
2017-11-22 11:15 ` Stephen Berman
@ 2017-11-22 17:05 ` Kendall Shaw
[not found] ` <mailman.4298.1511349362.27995.help-gnu-emacs@gnu.org>
2 siblings, 0 replies; 7+ messages in thread
From: Kendall Shaw @ 2017-11-22 17:05 UTC (permalink / raw)
To: help-gnu-emacs
On 11/21/2017 03:30 PM, B. T. Raven wrote:
> Dear Emacs gurus:
>
> I can perform this inteactive substitution
> CM-%: \(^[0-9]+ \)\(.+\) -> \2 \1)
> in order to change a buffer line prefixed with a number into one
> post-fixed with the same number but I can't figue out how to do the
> same programatically to a whole region. I started with this code:
>
> (defun verse-num-move-beg-to-end (beg end)
> "Move int-string and following space from beginning of line to end of
> line throughout region."
> (interactive "r")
> (goto-char beg)
> (while (<= (point) end)
> (re-search-forward "^[0-9]+ ")
> (setq num (substring (match-string 0) 0 -1)) ;; should be a string
> of ;;digits without trailing space
> (print num)
>
> ;; here the value generates a wrong argument error:
> setq: Wrong type argument: listp, #("234" 0 3 (fontified t))
> (type-of #("234" 0 3 (fontified t)))
>
> ;; I have a function which is a black box to to me but it works in the
> larger context I have it in. Does match-string do something like this
> implicitly (casting a list as a string?)
> ...
> (substring (match-string 0) 0 -1)
> (replace-match "" nil t)
>
>
> 234 asentuhasneothu ;; example buffer-line
re-search-forward signals an error if the search string isn't matched. I
don't know if that could explain the error you are seeing, but this
would prevent a non-local exit:
(cond
((re-search-forward "^[0-9]+ " nil t)
(setq num ...)
(print num))
(t
(goto-char end)))
Kendall
^ permalink raw reply [flat|nested] 7+ messages in thread
[parent not found: <mailman.4298.1511349362.27995.help-gnu-emacs@gnu.org>]
* Re: help with regexp function
[not found] ` <mailman.4298.1511349362.27995.help-gnu-emacs@gnu.org>
@ 2017-11-23 4:18 ` B. T. Raven
2017-11-23 15:20 ` Stephen Berman
[not found] ` <mailman.4372.1511450434.27995.help-gnu-emacs@gnu.org>
0 siblings, 2 replies; 7+ messages in thread
From: B. T. Raven @ 2017-11-23 4:18 UTC (permalink / raw)
To: help-gnu-emacs
Thanks, Stephen and Kendall. Stephen's solution is exactly what I wanted
except for the close-paren after the line number. What I needed to know
about is the just discovered regexp-quote and re-builder functions. What
I was relying on was the replace-match docs at C-hf whose syntax is much
more complicated than your concatenation of match-strings 1 and 2.
Since my thinking about the problem was so tentative I won't try to
remediate my code but just go with what Stephen wrote. Kendall wrote:
"
re-search-forward signals an error if the search string isn't matched. I
don't know if that could explain the error you are seeing, but this
would prevent a non-local exit:
(cond
((re-search-forward "^[0-9]+ " nil t)
(setq num ...)
(print num))
(t
(goto-char end)))
"
On 11/22/2017 05:15, Stephen Berman wrote:
> On Tue, 21 Nov 2017 17:30:15 -0600 "B. T. Raven" <btraven@nihilo.net>
wrote:
>
>> Dear Emacs gurus:
>>
>> I can perform this inteactive substitution
>> CM-%: \(^[0-9]+ \)\(.+\) -> \2 \1)
>> in order to change a buffer line prefixed with a number into one
post-fixed
>> with the same number but I can't figue out how to do the same
programatically
>> to a whole region. I started with this code:
>>
[...]
>
> Here's a pretty direct translation of the interactive substitution:
This works correctly but it isn't exactly what regexp-quote returns.
Is there a function that produces "^\\([0-9]+\\) \\(.*\\)$" from
"\(^[0-9]+ \)\(.+\)" ? Did you replace .+ with .* just for greater
generality?
>
> (defun verse-num-move-beg-to-end (beg end)
> "Move int-string and following space from beginning of line to
> end of line throughout region."
> (interactive "r")
> (goto-char beg)
> (while (<= (point) end)
> (re-search-forward "^\\([0-9]+\\) \\(.*\\)$")
> (replace-match (concat (match-string 2) " " (match-string 1) ")"))))
[...]
> I can't tell what the problem without seeing the code that causes it.
> Were you trying to treat the propertized string as a list because of the
> #(...) notation?
No, I don't understand that notation. I started with other regexp
functions like query-replace-regexp but was getting type errors and
general confusion.
>
>> ;; I have a function which is a black box to to me but it works in
the larger
>> context I have it in. Does match-string do something like this
implicitly
>> (casting a list as a string?)
>
> Not AFAIK.
Here is the function I was talking about:
(defun reverse-string (str)
(apply #'string (nreverse (string-to-list str))))
It sounded like (append #'string ... was recasting a list to a string.
[...]
>>
>> Any help apppreciated.
>>
>> Ed
>
> Steve Berman
>
Thanks again,
Ed
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: help with regexp function
2017-11-23 4:18 ` B. T. Raven
@ 2017-11-23 15:20 ` Stephen Berman
[not found] ` <mailman.4372.1511450434.27995.help-gnu-emacs@gnu.org>
1 sibling, 0 replies; 7+ messages in thread
From: Stephen Berman @ 2017-11-23 15:20 UTC (permalink / raw)
To: help-gnu-emacs
On Wed, 22 Nov 2017 22:18:14 -0600 "B. T. Raven" <btraven@nihilo.net> wrote:
[...]
> On 11/22/2017 05:15, Stephen Berman wrote:
>> On Tue, 21 Nov 2017 17:30:15 -0600 "B. T. Raven" <btraven@nihilo.net> wrote:
>>
>>> Dear Emacs gurus:
>>>
>>> I can perform this inteactive substitution CM-%: \(^[0-9]+ \)\(.+\)
>>> -> \2 \1) in order to change a buffer line prefixed with a number
>>> into one post-fixed with the same number but I can't figue out how
>>> to do the same programatically to a whole region. I started with
>>> this code: [...]
>>
>> Here's a pretty direct translation of the interactive substitution:
> This works correctly but it isn't exactly what regexp-quote returns.
Note that (regexp-quote "\(^[0-9]+ \)\(.+\)") returns this string:
"(\\^\\[0-9]\\+ )(\\.\\+)", which matches only the literal string
"(^[0-9]+ )(.+)", so it's not what you want.
> Is there a function that produces "^\\([0-9]+\\) \\(.*\\)$" from
> "\(^[0-9]+ \)\(.+\)" ?
I don't know of any. But in order for the Lisp reader to recognize a
backslash in a string as a backslash, you have to double it (because the
backslash is used as the escape character is the Lisp read syntax). So
you can just write your regexp as you would when using
query-replace-regexp and then double each of the backslashes to use it
in a Lisp program.
> Did you replace .+ with .* just for greater generality?
Yep.
[...]
>> I can't tell what the problem without seeing the code that causes it.
>> Were you trying to treat the propertized string as a list because of
>> the #(...) notation?
>
> No, I don't understand that notation. I started with other regexp
> functions like query-replace-regexp but was getting type errors and
> general confusion.
I still can't tell how such errors arose, but it's probably not worth
pursuing now.
>>> ;; I have a function which is a black box to to me but it works in
>>> the larger context I have it in. Does match-string do something like
>>> this implicitly (casting a list as a string?)
>>
>> Not AFAIK.
>
> Here is the function I was talking about:
> (defun reverse-string (str)
> (apply #'string (nreverse (string-to-list str))))
>
> It sounded like (append #'string ... was recasting a list to a string.
^^^^^^
apply
I'm not sure it's helpful to think of it like that, since using a list
is an artefact of the function definition here: `string' takes one or
more characters but Emacs Lisp functions cannot return multiple values,
only single values such as a list of characters. But you can dispense
with that intermediate step:
(defun reverse-string (str)
(let ((l (length str))
(nstr ""))
(dotimes (i l nstr)
(setq nstr (concat (string (aref str i)) nstr)))))
In fact, this is essentially how `nreverse' (and 'reverse') operate on
strings (so there's no need for `reverse-string'). In any case, I don't
see what this has to do with match-string.
Steve Berman
^ permalink raw reply [flat|nested] 7+ messages in thread
[parent not found: <mailman.4372.1511450434.27995.help-gnu-emacs@gnu.org>]
* Re: help with regexp function
[not found] ` <mailman.4372.1511450434.27995.help-gnu-emacs@gnu.org>
@ 2017-11-24 14:46 ` B. T. Raven
2017-11-24 16:28 ` Stephen Berman
0 siblings, 1 reply; 7+ messages in thread
From: B. T. Raven @ 2017-11-24 14:46 UTC (permalink / raw)
To: help-gnu-emacs
On 11/23/2017 09:20, Stephen Berman wrote:
>>> Here's a pretty direct translation of the interactive substitution:
>> This works correctly but it isn't exactly what regexp-quote returns.
>
> Note that (regexp-quote "\(^[0-9]+ \)\(.+\)") returns this string:
> "(\\^\\[0-9]\\+ )(\\.\\+)", which matches only the literal string
> "(^[0-9]+ )(.+)", so it's not what you want.
>
>> Is there a function that produces "^\\([0-9]+\\) \\(.*\\)$" from
>> "\(^[0-9]+ \)\(.+\)" ?
>
> I don't know of any. But in order for the Lisp reader to recognize a
> backslash in a string as a backslash, you have to double it (because the
> backslash is used as the escape character is the Lisp read syntax). So
> you can just write your regexp as you would when using
> query-replace-regexp and then double each of the backslashes to use it
> in a Lisp program.
Okay, thanks.
>
>> Did you replace .+ with .* just for greater generality?
>
> Yep.
>
>>
>> No, I don't understand that notation. I started with other regexp
>> functions like query-replace-regexp but was getting type errors and
>> general confusion.
>
> I still can't tell how such errors arose, but it's probably not worth
> pursuing now.
>
>>>> ;; I have a function which is a black box to to me but it works in
>>>> the larger context I have it in. Does match-string do something like
>>>> this implicitly (casting a list as a string?)
>>>
>>> Not AFAIK.
>>
>> Here is the function I was talking about:
>> (defun reverse-string (str)
>> (apply #'string (nreverse (string-to-list str))))
>>
>> It sounded like (append #'string ... was recasting a list to a string.
> ^^^^^^
> apply
Yes, because I tried to type rather than copypaste.
I was distracted by the # (what does it mean?)
>
> I'm not sure it's helpful to think of it like that, since using a list
> is an artefact of the function definition here: `string' takes one or
> more characters but Emacs Lisp functions cannot return multiple values,
> only single values such as a list of characters. But you can dispense
> with that intermediate step:
>
> (defun reverse-string (str)
> (let ((l (length str))
> (nstr ""))
> (dotimes (i l nstr)
> (setq nstr (concat (string (aref str i)) nstr)))))
>
> In fact, this is essentially how `nreverse' (and 'reverse') operate on
> strings (so there's no need for `reverse-string'). In any case, I don't
> see what this has to do with match-string.
That looks like it may be faster than what
I have now. Is it? Everything is in C except dotimes and string-to-list
according to the function docs.
Thanks again.
>
> Steve Berman
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: help with regexp function
2017-11-24 14:46 ` B. T. Raven
@ 2017-11-24 16:28 ` Stephen Berman
0 siblings, 0 replies; 7+ messages in thread
From: Stephen Berman @ 2017-11-24 16:28 UTC (permalink / raw)
To: help-gnu-emacs
On Fri, 24 Nov 2017 08:46:59 -0600 "B. T. Raven" <btraven@nihilo.net> wrote:
> On 11/23/2017 09:20, Stephen Berman wrote:
>
>>> It sounded like (append #'string ... was recasting a list to a string.
>> ^^^^^^
>> apply
> Yes, because I tried to type rather than copypaste.
> I was distracted by the # (what does it mean?)
Together with the apostrophe it stands for `function'. I can't explain
it better than the Elisp manual (info "(elisp) Anonymous Functions"):
-- Special Form: function function-object
This special form returns FUNCTION-OBJECT without evaluating it.
In this, it is similar to ‘quote’ (*note Quoting::). But unlike
‘quote’, it also serves as a note to the Emacs evaluator and
byte-compiler that FUNCTION-OBJECT is intended to be used as a
function. Assuming FUNCTION-OBJECT is a valid lambda expression,
this has two effects:
• When the code is byte-compiled, FUNCTION-OBJECT is compiled
into a byte-code function object (*note Byte Compilation::).
• When lexical binding is enabled, FUNCTION-OBJECT is converted
into a closure. *Note Closures::.
The read syntax ‘#'’ is a short-hand for using ‘function’. The
following forms are all equivalent:
(lambda (x) (* x x))
(function (lambda (x) (* x x)))
#'(lambda (x) (* x x))
>> I'm not sure it's helpful to think of it like that, since using a list
>> is an artefact of the function definition here: `string' takes one or
>> more characters but Emacs Lisp functions cannot return multiple values,
>> only single values such as a list of characters. But you can dispense
>> with that intermediate step:
>>
>> (defun reverse-string (str)
>> (let ((l (length str))
>> (nstr ""))
>> (dotimes (i l nstr)
>> (setq nstr (concat (string (aref str i)) nstr)))))
>>
>> In fact, this is essentially how `nreverse' (and 'reverse') operate on
>> strings (so there's no need for `reverse-string'). In any case, I don't
>> see what this has to do with match-string.
>
> That looks like it may be faster than what
> I have now. Is it? Everything is in C except dotimes and string-to-list
> according to the function docs.
I don't know if there's a measurable difference, but again, why do you
want `reverse-string' when you can just use `reverse' (or `nreverse')?
Steve Berman
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-11-24 16:28 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-11-21 23:30 help with regexp function B. T. Raven
2017-11-22 11:15 ` Stephen Berman
2017-11-22 17:05 ` Kendall Shaw
[not found] ` <mailman.4298.1511349362.27995.help-gnu-emacs@gnu.org>
2017-11-23 4:18 ` B. T. Raven
2017-11-23 15:20 ` Stephen Berman
[not found] ` <mailman.4372.1511450434.27995.help-gnu-emacs@gnu.org>
2017-11-24 14:46 ` B. T. Raven
2017-11-24 16:28 ` Stephen Berman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).