Лучший способ проанализировать строку адресов электронной почты

Похоже, что это обрабатывается в методе paint в классе BasicButtonUI (а затем в методе layout и, в конечном итоге, вплоть до метода SwingUtilities2.clipString) в версии Oracle JDK 8, по крайней мере. Подклассы BasicButtonUI, перезапись метода paint, а затем установка экземпляра этого подкласса в качестве пользовательского интерфейса на вашей кнопке должны позволить вам перезаписать это.

10
задан Tom Anderson 16 January 2009 в 20:34
поделиться

7 ответов

Вот решение, которое я предложил для выполнения этого:

String str = "Last, First <name@domain.com>, name@domain.com, First Last <name@domain.com>, \"First Last\" <name@domain.com>";

List<string> addresses = new List<string>();
int atIdx = 0;
int commaIdx = 0;
int lastComma = 0;
for (int c = 0; c < str.Length; c++)
{
if (str[c] == '@')
    atIdx = c;

if (str[c] == ',')
    commaIdx = c;

if (commaIdx > atIdx && atIdx > 0)
{
    string temp = str.Substring(lastComma, commaIdx - lastComma);
    addresses.Add(temp);
    lastComma = commaIdx;
    atIdx = commaIdx;
}

if (c == str.Length -1)
{
    string temp = str.Substring(lastComma, str.Legth - lastComma);
    addresses.Add(temp);
}
}

if (commaIdx < 2)
{
    // if we get here we can assume either there was no comma, or there was only one comma as part of the last, first combo
    addresses.Add(str);
}
2
ответ дан 3 December 2019 в 20:44
поделиться

Нет действительно легкого решения этого. Я рекомендовал бы делать немного конечного автомата, который читает символ символом, и сделайте работу тот путь. Как Вы сказал, разделение запятой будет не всегда работать.

Конечный автомат позволит Вам покрывать все возможности. Я уверен, что существуют многие другие, которых Вы еще не видели. Например: "Сначала В последний раз"

Ищите RFC об этом для обнаружения, каковы все возможности. Извините, я не знаю число. Существуют, вероятно, несколько, поскольку это - вид вещей, который развивается.

4
ответ дан 3 December 2019 в 20:44
поделиться

Рискуя тем, чтобы создать две проблемы, Вы могли создать регулярное выражение, которое соответствует любому из Ваших почтовых форматов. Используйте "|" для разделения форматов в этом regex. Затем можно выполнить его по входной строке и вытащить все соответствия.

public class Address
{
    private string _first;
    private string _last;
    private string _name;
    private string _domain;

    public Address(string first, string last, string name, string domain)
    {
        _first = first;
        _last = last;
        _name = name;
        _domain = domain;
    }

    public string First
    {
        get { return _first; }
    }

    public string Last
    {
        get { return _last; }
    }

    public string Name
    {
        get { return _name; }
    }

    public string Domain
    {
        get { return _domain; }
    }
}

[TestFixture]
public class RegexEmailTest
{
    [Test]
    public void TestThreeEmailAddresses()
    {
        Regex emailAddress = new Regex(
            @"((?<last>\w*), (?<first>\w*) <(?<name>\w*)@(?<domain>\w*\.\w*)>)|" +
            @"((?<first>\w*) (?<last>\w*) <(?<name>\w*)@(?<domain>\w*\.\w*)>)|" +
            @"((?<name>\w*)@(?<domain>\w*\.\w*))");
        string input = "First, Last <name@domain.com>, name@domain.com, First Last <name@domain.com>";

        MatchCollection matches = emailAddress.Matches(input);
        List<Address> addresses =
            (from Match match in matches
             select new Address(
                 match.Groups["first"].Value,
                 match.Groups["last"].Value,
                 match.Groups["name"].Value,
                 match.Groups["domain"].Value)).ToList();
        Assert.AreEqual(3, addresses.Count);

        Assert.AreEqual("Last", addresses[0].First);
        Assert.AreEqual("First", addresses[0].Last);
        Assert.AreEqual("name", addresses[0].Name);
        Assert.AreEqual("domain.com", addresses[0].Domain);

        Assert.AreEqual("", addresses[1].First);
        Assert.AreEqual("", addresses[1].Last);
        Assert.AreEqual("name", addresses[1].Name);
        Assert.AreEqual("domain.com", addresses[1].Domain);

        Assert.AreEqual("First", addresses[2].First);
        Assert.AreEqual("Last", addresses[2].Last);
        Assert.AreEqual("name", addresses[2].Name);
        Assert.AreEqual("domain.com", addresses[2].Domain);
    }
}

Существуют несколько вниз стороны к этому подходу. Каждый - это, это не проверяет строку. Если у Вас есть какие-либо символы в строке, которые не соответствуют одному из Ваших выбранных форматов, то те символы просто проигнорированы. Другой - это, принятые форматы все выражаются в одном месте. Вы не можете добавить новые форматы, не изменяя монолитный regex.

4
ответ дан 3 December 2019 в 20:44
поделиться

Нет никакого универсального простого решения этого. RFC, который Вы хотите, является RFC2822, который описывает все возможные конфигурации адреса электронной почты. Лучшее, которое Вы собираетесь получить, который будет корректен, должно реализовать основанный на состоянии токенизатор, который следует правилам, указанным в RFC.

2
ответ дан 3 December 2019 в 20:44
поделиться

Вот то, как я сделал бы это:

  • Можно попытаться стандартизировать данные как можно больше т.е. избавиться от таких вещей как <и> символы и все запятые после '.com'. Вам будут нужны запятые, которые разделяют имя и фамилию.
  • После избавления от дополнительных символов, помещенных каждая сгруппированная электронная почта, записывают в списке как строка. Можно использовать .com для определения, где разделить строку в случае необходимости.
  • После того, как у Вас будет список адресов электронной почты в списке строк, можно затем далее разделить адреса электронной почты с помощью только пробел в качестве разделителя.
  • Заключительный шаг должен определить то, что является именем, что является фамилией и т.д. Это было бы сделано путем проверки этих 3 компонентов на: запятая, которая указала бы, что это - фамилия; a., который указал бы на исполнительный адрес; и то, независимо от того, что оставляют, является именем. Если нет никакой запятой, то имя является первым, фамилия является второй и т.д.

    Я не знаю, является ли это самым кратким решением, но оно работало бы и не требует никаких усовершенствованных методов программирования
0
ответ дан 3 December 2019 в 20:44
поделиться

Вы могли использовать регулярные выражения, чтобы попытаться выделить это, судить этого парня:

^(?<name1>[a-zA-Z0-9]+?),? (?<name2>[a-zA-Z0-9]+?),? (?<address1>[a-zA-Z0-9.-_<>]+?)$

будет соответствовать: Last, First test@test.com; Last, First <test@test.com>; First last test@test.com; First Last <test@test.com>. Можно добавить другое дополнительное соответствие в regex в конце для взятия последнего сегмента First, Last <name@domain.com>, name@domain.com после того, как адрес электронной почты включается в угловые фигурные скобки.

Надежда это помогает несколько!

Править:

и конечно можно добавить больше символов к каждому из разделов, чтобы признать, что цитаты и т.д. для любого формата читаются в. Как sjbotha упомянутый, это могло быть трудно как строка, которая отправлена, находится не обязательно в формате набора.

Эта ссылка может дать Вам больше информации о соответствии И проверке адресов электронной почты с помощью регулярных выражений.

0
ответ дан 3 December 2019 в 20:44
поделиться

Я использую следующее регулярное выражение в Java для получения строки электронной почты от адреса электронной почты RFC:

[A-Za-z0-9]+[A-Za-z0-9._-]+@[A-Za-z0-9]+[A-Za-z0-9._-]+[.][A-Za-z0-9]{2,3}
-2
ответ дан 3 December 2019 в 20:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: