all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* 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

* 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

* 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

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.