正则表达式搜索按钮标记中不包含id的所有文件

时间:2015-03-17 14:02:28

标签: regex bash grep

我不知道正则表达式并且很少使用它。我正在尝试识别没有id的html按钮标签。搜索我最终得到了这个

$ grep -Prn '<button(.*)(?!\id)(.*)>' .

but search results came with <button ... id ...>. Like

<button id="criar_rascunho" class="botao-editar botao-claro" onclick="editarConteudoRoteiro('<?php echo $roteiro_versao->getId(); ?>','<?php echo $roteiro_release->getId(); ?>')">

<button class="botao-claro botao-progresso" data-titulo="<?php echo $disciplinaOfertaGrupo['disciplinaOferta']->getNome();?>" data-dofid="<?php echo $disciplinaOfertaGrupo['disciplinaOferta']->getId(); ?>"><?php echo $this->translate('ver-progresso'); ?></button>

<button class="excluir-disciplina excluir-disciplina-icones"></button></td>

换句话说,两者都是

<button ... >

<button ... id ...>

在搜索结果中。

3 个答案:

答案 0 :(得分:1)

很快就可以在不使用预测的情况下完成

grep -v '<button[^>]*id.*>'

来自man grep

  

-v, - 反转匹配                 反转匹配感,选择不匹配的线条。 (-v                 由POSIX指定。)

<强>测试

$ cat input
<button ... >
<button ...  id >

$ grep -v '<button[^>]*id.*>' input
<button ... >

如果您仍希望使用预测,只需将之前的任何内容更改为前瞻,以及

grep -P '<button(?![^>]*id)'

<强>测试

$ cat input
<button ... >
<button ...  id >

$ grep -P '<button(?![^>]*id)' input
<button ... >

答案 1 :(得分:1)

您可以尝试下面的内容。

grep -Prn '<button\b(?![^>]*\bid\b)[^>]*>' 

(?![^>]*\bid\b)否定前瞻声明标记本身内的<button子字符串不会跟随匹配id

示例:

$ cat file
<button ... >
<button ...  id >
$ grep -Prn '<button\b(?![^>]*\bid\b)[^>]*>' file
1:<button ... >

答案 2 :(得分:1)

正则表达式不是解析[X] HTML的好工具。除非你简化了关于输入形式的假设,否则不可能正确地做到这一点,即使这样也很难。使用真正的解析器会更好。

此外,正则表达式不是一件事,而是一系列事物。由POSIX grep处理的正则表达式语言与Perl处理的正则语言不同,后者与Java处理的正则语言稍有不同,这与Javascript处理的不同等等。我是只谈谈grep的方言,但......

此外,grep是面向行的工具,而HTML不是面向行的语言。这是一个无法解决的不匹配,除非你愿意假设你的按钮元素永远不会跨越多行,如下所示:

<button
  id='my_id' />

此外,由于grep同样是 line 定向工具,即使你有一个有效的正则表达式,它也会匹配包含两个或更多<button>的行其中一些具有id属性而另一些则没有的元素。这可能令人困惑。

在一般意义上,对于模式匹配器来正确完成工作,它必须匹配整个标签,包括这些标签中的每个属性,以不允许任何属性具有名称“id”。必须确保避免考虑跨越两个或多个标记的子字符串,并且不得排除子字符串“id”显示为完整属性名称以外的任何标记。

这个Perl正则表达式的怪物(因为你使用grep -P)会比你提出的更准确:

<button(?:\s+(?:(?!id)[A-Za-z0-9.-]+|id[A-Za-z0-9.-]+)(?:\s*=\s*(?:[^ \t\n\r>'"]+|'[^']*'|"[^"]*")))*\s*/?>

它匹配一个完整的HTML开始标记或空标记(它不会被同一行上的多个标记所欺骗),其中没有任何属性(如果有)被命名为“id”。它不会被包含“id”作为子字符串的三个字符或更长的属性名称所欺骗,也不会被出现在属性值中的“id”所欺骗。如果你想要混合大小写匹配,那么可以添加它而不会有太多额外的困难。

另一方面,它还会匹配模仿按钮开始的字符数据或没有id的空标记,当与grep一起使用时,它将无法匹配任何跨越多行的按钮开始标记。如果它们包含的字符属性名称既不是(非重音)拉丁字母,也不是数字,也不是'。',也不是' - ',它也将无法匹配有效的开始标记。它可能有其他缺点。