无法匹配正则表达式与sed

问题描述:

我试图匹配(\^|\~?)(\d|x|\*)+\.(\d|x|\*)+\.(\d|x|\*)+sed模式,但没有运气。 我通过运行该文件是这样的:无法匹配正则表达式与sed

{ 
    "name": "something", 
    "version": "0.0.1", 
    "description": "some desc", 
    "main": "gulpfile.js", 
    "directories": { 
    "test": "tests" 
    }, 
    "dependencies": { 
    "babel-polyfill": "^6.7.4", 
    "babel-preset-es2015": "^6.6.0", 
    "babel-preset-react": "^6.5.0", 
    "gulp-clean": "^0.3.2", 
    "jquery": "^2.1.4", 
    "lodash": "^4.0.0", 
    "moment": "^2.13.0", 
    "moment-timezone": "^0.5.0", 
    "radium": "^0.16.2", 
    "react": "^15.1.0", 
    "react-bootstrap-sweetalert": "^1.1.10", 
    "react-dom": "^15.1.0", 
    "react-timeago": "^2.2.1", 
    "sprintf": "^0.1.5", 
    "smoothscroll": "~0.2.2" 
    }, 
    "devDependencies": { 
    "babel": "^6.3.26", 
    "babelify": "^7.2.0", 
    "browserify": "~12.0.1", 
    "console-stamp": "^0.2.0", 
    "estraverse-fb": "^1.3.1", 
    "gulp": "^3.9.0", 
    "gulp-concat": "^2.6.0", 
    "gulp-sass": "^2.1.1", 
    "gulp-sourcemaps": "^1.6.0", 
    "gulp-util": "^3.0.7", 
    "lodash": "4.5.1", 
    "lodash.assign": "^3.2.0", 
    "lodash.isfunction": "^3.0.8", 
    "lodash.reduce": "^4.3.0", 
    "node-sass": "3.4.2", 
    "react-bootstrap": "^0.29.4", 
    "react-intl": "2.1.0", 
    "reactify": "1.1.1", 
    "sweetalert": "^1.1.3", 
    "vinyl": "^1.1.0", 
    "vinyl-buffer": "^1.0.0", 
    "vinyl-source-stream": "^1.1.0", 
    "watchify": "^3.4.0", 
    "jsx-to-string": "~0.2.11" 
    }, 
    "optionalDependencies": { 
    "pkg-save": "~1.0.2" 
    }, 
    "scripts": { 
    "test": "echo \"Error: no test specified\" && exit 1" 
    }, 
    "repository": { 
    "type": "git", 
    "url": "someurl" 
    }, 
    "author": "authorname", 
    "license": "MIT" 
} 

正如你可以看到它regexr所期望的模式匹配(也匹配“版本”但那是另外一个问题我以后会解决): http://regexr.com/3e324

我调用调用SED使用下面的命令:
cat package.json | sed 's/(\^|\~?)(\d|x|\*)+\.(\d|x|\*)+\.(\d|x|\*)+/Hello/g' -r

为了简洁起见,它输出类似的信息(即,未过滤的输入。):

... 
"dependencies": { 
    "babel-polyfill": "^6.7.4", 
    "babel-preset-es2015": "^6.6.0", 
    "babel-preset-react": "^6.5.0", 
    "gulp-clean": "^0.3.2", 
... 

它应该用“你好”来代替所有数字。
我在做什么错? (我试过/gm
或不使用正确的正则表达式引擎(我通过-r选项来利用扩展正则表达式)?

+1

我不知道你的'sed'问题的答案(对不起),但我只想提到,如果你正在做一些像这样的JSON工作,你可能想使用一个更适合它的工具,如[jq] (https://stedolan.github.io/jq/) – Matt

+0

谢谢,这可能是我需要的! 我需要一个可以直接操作package.json文件的工具,并且可以完全控制正在更改的内容。 –

+0

我已经用'[0-9]'而不是'\ d'修复了它。 (如果你处理了很多JSON,我仍然使用'jq') – Aaron

虽然POSIX正则表达式支持一些命名字符类,像[[:digit:]][[:alnum:]],他们不支持速记类,如\d\w

一些GNU扩展带来速记类的支持,但他们,\w\W\s\S根据regular-expressions.info仅限于少数人。

通过将正则表达式中的\d替换为[0-9]我能够转换您的文档。正则表达式变成(\^|\~?)([0-9]|x|\*)+\.([0-9]|x|\*)+\.([0-9]|x|\*)+,或更好[~^]([0-9x*]+\.){2}[0-9x*](感谢Ed Morton!)。

作为一个侧面说明,你的命令可以改写为以下,其中不使用cat

sed -E 's/[~^]([0-9x*]+\.){2}[0-9x*]/Hello/' package.json 

正如马特指出,你会使用JSON解析器会更好,如jq

+1

由于'-r'而不是'-E',你的脚本目前是GNU sed-specific。启用EREs,并且你正在逃避不需要转义的角色,例如'〜'和像'([0-9] | x | \ *)+'的RE段不必要的冗长/复杂等。我明白那是因为你复制了OPs非功能脚本,但它可以很好地清理它 - 整个事物可以更便携地书写,就像(未经测试,但如果不完全正确的话,它将会接近)'sed -E's/[〜^]([0-9x *] + \){2} [0-9x *] /你好/''。 –

+1

谢谢,我已经测试过(使用GNU sed)并更新了我的答案。我不知道'-E'存在,它甚至不出现在我的'man sed'中! – Aaron

+1

是的。它在BSD sed和更新的GNU seds中得到了支持,作为-r的替代方案,但是GNU人员尚未更新文档。 –