Трудно найти регулярное выражение, которое работает для всех случаев IPv6. Их, как правило, трудно поддерживать, они не легко читаемы и могут вызвать проблемы с производительностью. Следовательно, я хочу поделиться альтернативным решением, которое я разработал: Регулярное выражение (RegEx) для IPv6 Отдельно от IPv4
Теперь вы можете спросить, что «этот метод находит только IPv6, как я могу найти IPv6 в тексте или файле? " Вот методы для этой проблемы.
Примечание. Если вы не хотите использовать класс IPAddress в .NET, вы также можете заменить его на мой метод . Он также охватывает отображенные IPv4 и специальные случаи, а IPAddress не распространяется.
class IPv6
{
public List FindIPv6InFile(string filePath)
{
Char ch;
StringBuilder sbIPv6 = new StringBuilder();
List listIPv6 = new List();
StreamReader reader = new StreamReader(filePath);
do
{
bool hasColon = false;
int length = 0;
do
{
ch = (char)reader.Read();
if (IsEscapeChar(ch))
break;
//Check the first 5 chars, if it has colon, then continue appending to stringbuilder
if (!hasColon && length < 5)
{
if (ch == ':')
{
hasColon = true;
}
sbIPv6.Append(ch.ToString());
}
else if (hasColon) //if no colon in first 5 chars, then dont append to stringbuilder
{
sbIPv6.Append(ch.ToString());
}
length++;
} while (!reader.EndOfStream);
if (hasColon && !listIPv6.Contains(sbIPv6.ToString()) && IsIPv6(sbIPv6.ToString()))
{
listIPv6.Add(sbIPv6.ToString());
}
sbIPv6.Clear();
} while (!reader.EndOfStream);
reader.Close();
reader.Dispose();
return listIPv6;
}
public List FindIPv6InText(string text)
{
StringBuilder sbIPv6 = new StringBuilder();
List listIPv6 = new List();
for (int i = 0; i < text.Length; i++)
{
bool hasColon = false;
int length = 0;
do
{
if (IsEscapeChar(text[length + i]))
break;
//Check the first 5 chars, if it has colon, then continue appending to stringbuilder
if (!hasColon && length < 5)
{
if (text[length + i] == ':')
{
hasColon = true;
}
sbIPv6.Append(text[length + i].ToString());
}
else if (hasColon) //if no colon in first 5 chars, then dont append to stringbuilder
{
sbIPv6.Append(text[length + i].ToString());
}
length++;
} while (i + length != text.Length);
if (hasColon && !listIPv6.Contains(sbIPv6.ToString()) && IsIPv6(sbIPv6.ToString()))
{
listIPv6.Add(sbIPv6.ToString());
}
i += length;
sbIPv6.Clear();
}
return listIPv6;
}
bool IsEscapeChar(char ch)
{
if (ch != ' ' && ch != '\r' && ch != '\n' && ch!='\t')
{
return false;
}
return true;
}
bool IsIPv6(string maybeIPv6)
{
IPAddress ip;
if (IPAddress.TryParse(maybeIPv6, out ip))
{
return ip.AddressFamily == AddressFamily.InterNetworkV6;
}
else
{
return false;
}
}
}
name_map = {'oldcol1': 'newcol1', 'oldcol2': 'newcol2', 'oldcol3': 'newcol3'...}
for row in rows:
# Each row is a dict of the form: {'oldcol1': '...', 'oldcol2': '...'}
row = dict((name_map[name], val) for name, val in row.iteritems())
...
или в Python2.7 + с понимания Dict :
for row in rows:
row = {name_map[name]: val for name, val in row.items()}
rows = [{"col1":"data1a","col2":"data2a"},{"col1":"data1b","col2":"data2b"}]
name_map = {"col1":"newcol1","col2":"newcol2"}
new_rows = [dict(zip(map(lambda x: name_map[x], r.keys()), r.values())) for r in rows]
это, что Вы после?
Эта функция позволит Вам повторно отобразить только ключи, которые необходимо изменить.
def key_remapper(dict: dict):
return {remap_dictionary.get(k, v): v for k, v in dict.items()}