3

This problem came to me today. I'm working in a web-based (Struts 2) project with lots of JSPs, and most of input, select, table and a elements are defined with only with the name attribute, no id set, such as:

<input name="myname" class="myclass" value="" type="text"/>

So far so good, except that unfortunately there's a lot of javascript validation for those fields, and as far as I could read the code before leaving most of them actually refer to the elements with document.getElementById.

The catch here is that this is an old application (not that much old actually) only compatible with IE-6 and IE-7 (I didn't searched the net in order to understand how IE actually seems to find the element only with the name attribute, but I guess it must do something). No surprise every other single browser complains and cries.

So, I'm trying to come up with a simple solution: look up all JSPs that defines input, select, table and a elements with the name attribute but not id in order to fix the HTML.

Using my good ol' friend http://rubular.com I came up with the following:

/<(?:(input|select|a|table))\s+((?!id).)*>

This will catch every referred element without id. But how can I actually assert that only those with name are matched?

Oh, another important point. The definition of the elements are in a single line, so it's most probable that there arent't such things as:

<input name="..."
       class="..."/>
4

4 回答 4

6

尝试这个:

<(?:input|select|a|table)\s+(?=[^>]*\bname\s*=)(?![^>]*\bid\s*=)[^>]*>

解释:

<                           "<"
(?:input|select|a|table)    One of "input", "select", "a", "table"
\s+                         Whitespace
(?=                         Positive lookahead
[^>]*                           Anything up to but excluding ">"
\b                              Word boundary
name                            "name"
\s*                             Possible whitespace
=                               "="
)
(?!                         Negative lookahead
[^>]*                           Anything up to but excluding ">"
\b                              Word boundary
id                              "id"
\s*                             Possible whitespace
=                               "="
)
[^>]*                       Anything up to but excluding ">"
>                           ">"
于 2012-11-08T02:45:57.823 回答
2

免责声明:

每个人都会告诉你不要使用正则表达式来解析 HTML,他们是对的。也就是说,以下正则表达式解决方案对于一次性任务应该做得相当不错(如果不考虑 100% 的可靠性)。

正则表达式匹配具有一个属性但没有另一个属性的标签:

以下经过测试的 PHP 脚本使用(完全注释的)正则表达式来匹配INPUT、和具有属性但没有属性SELECT的元素的开始标记。该脚本在每个开始标记中插入一个与现有属性相同的新属性:TABLEANAMEIDIDNAME

<?php // test.php Rev:20121107_2100
$re = '%
    # Match HTML 4.01 element start tags with NAME but no ID attrib.
    (                      # $1: Everything up to tag close delimiter.
      <                    # Start tag open delimiter.
      (?:input|select|table|a)\b  # Element name.
      (?:                  # Zero or more attributes before NAME.
        \s+                # Attributes are separated by whitespace.
        (?!name\b|id\b)    # Only non-NAME, non-ID before NAME attrib.
        [A-Za-z][\w\-:.]*  # Attribute name is required.
        (?:                # Attribute value is optional.
          \s*=\s*          # Name and value separated by =
          (?:              # Group for value alternatives.
            "[^"]*"        # Either a double-quoted string,
          | \'[^\']*\'     # or a single-quoted string,
          | [\w\-:.]+      # or a non-quoted string.
          )                # End group of value alternatives.
        )?                 # Attribute value is optional.
      )*                   # Zero or more attributes before NAME.
      \s+                  # NAME attribute is separated by whitespace.
      name                 # NAME attribute name is required.
      \s*=\s*              # Name and value separated by =
      (                    # $2: NAME value.
        "[^"]*"            # Either a double-quoted string,
      | \'[^\']*\'         # or a single-quoted string,
      | [\w\-:.]+          # or a non-quoted string.
      )                    # $2: NAME value.
      (?:                  # Zero or more attributes after NAME.
        \s+                # Attributes are separated by whitespace.
        (?!id\b)           # Only non-ID attribs after NAME attrib.
        [A-Za-z][\w\-:.]*  # Attribute name is required.
        (?:                # Attribute value is optional.
          \s*=\s*          # Name and value separated by =
          (?:              # Group for value alternatives.
            "[^"]*"        # Either a double-quoted string,
          | \'[^\']*\'     # or a single-quoted string,
          | [\w\-:.]+      # or a non-quoted string.
          )                # End group of value alternatives.
        )?                 # Attribute value is optional.
      )*                   # Zero or more attributes after NAME.
    )                      # $1: Everything up to close delimiter.
    # Insert missing ID attribute here...
    (\s*/?>)               # $3: Start tag close delimiter.
    %ix';
$html = file_get_contents('testdata.html');
$html = preg_replace($re, "$1 id=$2$3", $html);
file_put_contents('testdata_out.html', $html);
?>
于 2012-11-08T05:30:27.543 回答
0

如果我们在 javascript 中使用 getElementById,那么如果存在与 id 中使用的名称相同的元素,它在 Internet Explorer 中有效,但在所有其他浏览器(Firefox、Chrome、Safari 等)中无效。

可以通过以下代码消除。

function includeIdIfNotExist(element) {
    var id = element.getAttribute('id');
    var name = element.getAttribute('name');
    if (name && !id) {
        element.id = name;
    }
}
function addMissingId() {
    var elementsToAddId = ['input', 'select'];
    for (var j = 0; j < elementsToAddId.length; j++) {
        var inputElements = document.getElementsByTagName(elementsToAddId[j]);
        for (var i = 0; i < inputElements.length; i++) {
            includeIdIfNotExist(inputElements[i]);
        }
    }
}
document.onload = addMissingId();
于 2015-12-01T09:14:49.693 回答
0

如果你想搜索有名字但没有id的元素,并设置id等于名字,你可以进行如下的查找和替换:

寻找:

(<(?:input|select|table|form|textarea)\s+)(?=[^>]*\bname\s*="(\w+)")((?![^>]*\bid\s*=)[^>]*>)

它适用于输入、选择、表格、表单、文本区域。您可以从input|select|table|form|textarea部分添加或删除 html 标签。它还将检查元素是否具有 id

用。。。来代替:

$1id="$2" $3

这将在您之前选择的 html 标记上添加 id="[nameValue]" ,该标记具有名称但没有 id。

希望能帮助到你!

于 2018-01-16T15:37:37.317 回答