mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
updated for version 7.4.241
Problem: The string returned by submatch() does not distinguish between a NL from a line break and a NL that stands for a NUL character. Solution: Add a second argument to return a list. (ZyX)
This commit is contained in:
parent
fe5aab63fe
commit
41571769c9
@ -1990,7 +1990,8 @@ strridx( {haystack}, {needle} [, {start}])
|
||||
Number last index of {needle} in {haystack}
|
||||
strtrans( {expr}) String translate string to make it printable
|
||||
strwidth( {expr}) Number display cell length of the String {expr}
|
||||
submatch( {nr}) String specific match in ":s" or substitute()
|
||||
submatch( {nr}[, {list}]) String or List
|
||||
specific match in ":s" or substitute()
|
||||
substitute( {expr}, {pat}, {sub}, {flags})
|
||||
String all {pat} in {expr} replaced with {sub}
|
||||
synID( {lnum}, {col}, {trans}) Number syntax ID at {lnum} and {col}
|
||||
@ -5797,12 +5798,23 @@ strwidth({expr}) *strwidth()*
|
||||
Ambiguous, this function's return value depends on 'ambiwidth'.
|
||||
Also see |strlen()|, |strdisplaywidth()| and |strchars()|.
|
||||
|
||||
submatch({nr}) *submatch()*
|
||||
submatch({nr}[, {list}]) *submatch()*
|
||||
Only for an expression in a |:substitute| command or
|
||||
substitute() function.
|
||||
Returns the {nr}'th submatch of the matched text. When {nr}
|
||||
is 0 the whole matched text is returned.
|
||||
Note that a NL in the string can stand for a line break of a
|
||||
multi-line match or a NUL character in the text.
|
||||
Also see |sub-replace-expression|.
|
||||
|
||||
If {list} is present and non-zero then submatch() returns
|
||||
a list of strings, similar to |getline()| with two arguments.
|
||||
NL characters in the text represent NUL characters in the
|
||||
text.
|
||||
Only returns more than one item for |:substitute|, inside
|
||||
|substitute()| this list will always contain one or zero
|
||||
items, since there are no real line breaks.
|
||||
|
||||
Example: >
|
||||
:s/\d\+/\=submatch(0) + 1/
|
||||
< This finds the first number in the line and adds one to it.
|
||||
|
31
src/eval.c
31
src/eval.c
@ -8129,7 +8129,7 @@ static struct fst
|
||||
{"strridx", 2, 3, f_strridx},
|
||||
{"strtrans", 1, 1, f_strtrans},
|
||||
{"strwidth", 1, 1, f_strwidth},
|
||||
{"submatch", 1, 1, f_submatch},
|
||||
{"submatch", 1, 2, f_submatch},
|
||||
{"substitute", 4, 4, f_substitute},
|
||||
{"synID", 3, 3, f_synID},
|
||||
{"synIDattr", 2, 3, f_synIDattr},
|
||||
@ -17890,9 +17890,32 @@ f_submatch(argvars, rettv)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string =
|
||||
reg_submatch((int)get_tv_number_chk(&argvars[0], NULL));
|
||||
int error = FALSE;
|
||||
char_u **match;
|
||||
char_u **s;
|
||||
listitem_T *li;
|
||||
int no;
|
||||
int retList = 0;
|
||||
|
||||
no = (int)get_tv_number_chk(&argvars[0], &error);
|
||||
if (error)
|
||||
return;
|
||||
error = FALSE;
|
||||
if (argvars[1].v_type != VAR_UNKNOWN)
|
||||
retList = get_tv_number_chk(&argvars[1], &error);
|
||||
if (error)
|
||||
return;
|
||||
|
||||
if (retList == 0)
|
||||
{
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = reg_submatch(no);
|
||||
}
|
||||
else
|
||||
{
|
||||
rettv->v_type = VAR_LIST;
|
||||
rettv->vval.v_list = reg_submatch_list(no);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -10,6 +10,7 @@ char_u *regtilde __ARGS((char_u *source, int magic));
|
||||
int vim_regsub __ARGS((regmatch_T *rmp, char_u *source, char_u *dest, int copy, int magic, int backslash));
|
||||
int vim_regsub_multi __ARGS((regmmatch_T *rmp, linenr_T lnum, char_u *source, char_u *dest, int copy, int magic, int backslash));
|
||||
char_u *reg_submatch __ARGS((int no));
|
||||
list_T *reg_submatch_list __ARGS((int no));
|
||||
regprog_T *vim_regcomp __ARGS((char_u *expr_arg, int re_flags));
|
||||
void vim_regfree __ARGS((regprog_T *prog));
|
||||
int vim_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
|
||||
|
79
src/regexp.c
79
src/regexp.c
@ -7897,6 +7897,85 @@ reg_submatch(no)
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for the submatch() function with the optional non-zero argument: get
|
||||
* the list of strings from the n'th submatch in allocated memory with NULs
|
||||
* represented in NLs.
|
||||
* Returns a list of allocated strings. Returns NULL when not in a ":s"
|
||||
* command, for a non-existing submatch and for any error.
|
||||
*/
|
||||
list_T *
|
||||
reg_submatch_list(no)
|
||||
int no;
|
||||
{
|
||||
char_u *s;
|
||||
linenr_T slnum;
|
||||
linenr_T elnum;
|
||||
colnr_T scol;
|
||||
colnr_T ecol;
|
||||
int i;
|
||||
list_T *list;
|
||||
int error = FALSE;
|
||||
|
||||
if (!can_f_submatch || no < 0)
|
||||
return NULL;
|
||||
|
||||
if (submatch_match == NULL)
|
||||
{
|
||||
slnum = submatch_mmatch->startpos[no].lnum;
|
||||
elnum = submatch_mmatch->endpos[no].lnum;
|
||||
if (slnum < 0 || elnum < 0)
|
||||
return NULL;
|
||||
|
||||
scol = submatch_mmatch->startpos[no].col;
|
||||
ecol = submatch_mmatch->endpos[no].col;
|
||||
|
||||
list = list_alloc();
|
||||
if (list == NULL)
|
||||
return NULL;
|
||||
|
||||
s = reg_getline_submatch(slnum) + scol;
|
||||
if (slnum == elnum)
|
||||
{
|
||||
if (list_append_string(list, s, ecol - scol) == FAIL)
|
||||
error = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (list_append_string(list, s, -1) == FAIL)
|
||||
error = TRUE;
|
||||
for (i = 1; i < elnum - slnum; i++)
|
||||
{
|
||||
s = reg_getline_submatch(slnum + i);
|
||||
if (list_append_string(list, s, -1) == FAIL)
|
||||
error = TRUE;
|
||||
}
|
||||
s = reg_getline_submatch(elnum);
|
||||
if (list_append_string(list, s, ecol) == FAIL)
|
||||
error = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s = submatch_match->startp[no];
|
||||
if (s == NULL || submatch_match->endp[no] == NULL)
|
||||
return NULL;
|
||||
list = list_alloc();
|
||||
if (list == NULL)
|
||||
return NULL;
|
||||
if (list_append_string(list, s,
|
||||
(int)(submatch_match->endp[no] - s)) == FAIL)
|
||||
error = TRUE;
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
list_free(list, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
#endif
|
||||
|
||||
static regengine_T bt_regengine =
|
||||
|
Binary file not shown.
Binary file not shown.
@ -117,6 +117,7 @@ STARTTEST
|
||||
:set cpo&
|
||||
:$put =\"\n\nTEST_5:\"
|
||||
:$put =substitute('A123456789', 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\=submatch(0) . submatch(9) . submatch(8) . submatch(7) . submatch(6) . submatch(5) . submatch(4) . submatch(3) . submatch(2) . submatch(1)', '')
|
||||
:$put =substitute('A123456789', 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\=string([submatch(0, 1), submatch(9, 1), submatch(8, 1), submatch(7, 1), submatch(6, 1), submatch(5, 1), submatch(4, 1), submatch(3, 1), submatch(2, 1), submatch(1, 1)])', '')
|
||||
/^TEST_6
|
||||
ENDTEST
|
||||
|
||||
@ -142,6 +143,7 @@ STARTTEST
|
||||
:$put =\"\n\nTEST_7:\"
|
||||
:$put =substitute('A
A', 'A.', '\=submatch(0)', '')
|
||||
:$put =substitute(\"B\nB\", 'B.', '\=submatch(0)', '')
|
||||
:$put =substitute(\"B\nB\", 'B.', '\=string(submatch(0, 1))', '')
|
||||
:$put =substitute('-bb', '\zeb', 'a', 'g')
|
||||
:$put =substitute('-bb', '\ze', 'c', 'g')
|
||||
/^TEST_8
|
||||
|
@ -90,6 +90,7 @@ l
|
||||
|
||||
TEST_5:
|
||||
A123456789987654321
|
||||
[['A123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], ['2'], ['1']]
|
||||
|
||||
|
||||
TEST_6:
|
||||
@ -103,6 +104,8 @@ TEST_7:
|
||||
A
A
|
||||
B
|
||||
B
|
||||
['B
|
||||
']B
|
||||
-abab
|
||||
c-cbcbc
|
||||
|
||||
|
@ -734,6 +734,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
241,
|
||||
/**/
|
||||
240,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user