-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gsub breaks \b for checking word boundaries #1425
Comments
@thedward - As you've discovered, jq's interpretation of the "g" in gsub is currently different from the one you have in mind. Here's one way to achieve the effect you want:
Example:
|
It's also currently different than documented. :-) I'm trying to write a correct implementation — if I succeed, I'll make a pull request. |
@itchyny wrote:
With respect to the example given at the top of this thread, please note that gsub is working as intended, that is, in accordance with the idea that |
@pkoppstein where is this behavior specified? |
@thedward - I wrote In any case, my hope is that whatever issues there may regarding the "iterative application" interpretation of gsub should not get in the way of fixing the infinite looping behavior described in #1206 and #2148. |
@pkoppstein, I was just hoping there was a source other than the manual to shed more light on this. Regardless, I don't agree that the existing behavior is consistent with the manual or with your informal specification because the regular expression I also have a hard time accepting the idea that someone intended the existing behavior both because it violates the principal of least surprise and because it makes the function less useful without gaining anything in return. I really don't understand why you'd want to reframe this as anything other than a bug. Since changing the behavior could conceivably break existing programs, it's certainly possible to argue it's a documentation bug at this point, but it's definitely a bug. p.s. I'm really excited to see jq development picking up some speed! |
@thedward @itchyny - The proposed new version of gsub (#2624) addresses this and many other issues. The new version uses (The tests are presented as triples, each of which can be read as:
|
… uniq(stream) The primary purpose of this commit (which supercedes PR jqlang#2624) is to rectify most problems with `gsub` (and also `sub` with the "g" option), in particular jqlang#1425 ('\b'), jqlang#2354 (lookahead), and jqlang#2532 (regex == "^(?!cd ).*$|^cd ";"")). This commit also partly resolves jqlang#2148 and jqlang#1206 in that `gsub` no longer loops infinitely; however, because the new `gsub` depends critically on match(_;"g"), the behavior when regex == "" is sometimes non-standard. [*1] Since the new sub/3 relies on uniq/1, that has been added as well [*2]. The documentation has been updated to reflect the fact that `sub` and `gsub` are intended to be regular in the second argument. [*3] Also, _nwise/1 has been tweaked to take advantage of TCO. Footnotes: [*1] Using the new gsub, '"a" | gsub( ""; "a")' emits "aa" rather than "aaa" as would be standard. This is nevertheless better than the infinite loop behavior of jq 1.6 in this case. With one exception (as explained in [*2]), the new gsub is implemented as though match/2 behavior is correct. That is, bugs in `gsub` behavior will most likely have their origin in `match/2`. [*2] `uniq/1` adopts the Unix/Linux name and semantics; it is needed for the following test case: gsub("(?=u)"; "u") "qux" "quux" Without this functionality: Test jqlang#23: 'gsub("(?=u)"; "u")' at line number 100 *** Expected "quux", but got "quuux" for test at line number 102: gsub("(?=u)"; "u") The root of the problem here is `match`: if `match` is fixed, then gsub would not need `untie`. The addition of `uniq` as a top-level function should be a non-issue relative to general concern about builtins.jq bloat: the line count of the new builtin.jq is significantly reduced overall, and the number of defs is actually reduced by 1 (from 111 (ignoring a redundant def) to 110). [*3] See e.g. jqlang#513 (comment)
The primary purpose of this commit is to rectify most problems with `gsub` (and also `sub` with the `g` option), in particular fix #1425 ('\b'), fix #2354 (lookahead), and fix #2532 (regex == `"^(?!cd ).*$|^cd "`). This commit also partly resolves #2148 and resolves #1206 in that `gsub` no longer loops infinitely; however, because the new `gsub` depends critically on `match/2`, the behavior when regex == `""` is sometimes non-standard. The documentation has been updated to reflect the fact that `sub` and `gsub` are intended to be regular in the second argument. Also, `_nwise/1` has been tweaked to take advantage of TCO.
When I run the following program with
jq -n
:Expected Output:
Actual Output:
I've got a workaround for my particular use case:
The text was updated successfully, but these errors were encountered: