Как я могу предотвратить удаление апострофов только из середины строк?

Мне нужно сохранить слова только с буквенно-цифровыми символами, дефисами и апострофами. У меня есть все, кроме апострофов в настоящее время. Апостроф в таких словах, как не, не и не удаляется с помощью этого кода:

Regex onlyAlphanumericAndDash = new Regex("[^a-zA-Z0-9 -]");
. . .
foreach (string line in doc1StrArray) // doc1StrArray populated in FindAndStorePhrasesFoundInBothDocs()
{
    trimmedLine = line;
    // first replace the "long dash" with a space (otherwise the dashed words run together:
    // "consecrated—we" becomes "consecratedwe"
    trimmedLine = trimmedLine.Replace("—", " ");
    trimmedLine = onlyAlphanumericAndDash.Replace(trimmedLine, "");
    string[] subLines = trimmedLine.Split();
    foreach (string whirred in subLines)
    {
        if (String.IsNullOrEmpty(whirred)) continue;
        _whirred = whirred.Trim();
        iWordsInDoc1++;
        slAllDoc1Words.Add(_whirred);
        if (IgnoreWord(_whirred)) continue;
        InsertIntoWordStatsTable(_whirred, 1, 0);
    }
}

Мне нужно сохранить апострофы, но только когда они внутри слова. Другими словами, апострофы в конце слова должны быть обрезаны, а также в начале (когда это одинарная кавычка); но апострофы внутри слова — другими словами, те, которые указывают на сокращения, которых не было — должны быть сохранены.

Что мне нужно добавить в регулярное выражение или как мне нужно изменить его, чтобы выполнить это?


person B. Clay Shannon    schedule 28.06.2020    source источник
comment
Не могли бы вы предоставить ожидаемый ввод и вывод   -  person vivek nuna    schedule 28.06.2020
comment
Помогает ли это?   -  person    schedule 28.06.2020
comment
@viveknuna: Ожидаемые примеры входных данных: не Шеннон Ожидаемый результат: не Шеннон   -  person B. Clay Shannon    schedule 28.06.2020


Ответы (3)


Меня немного смущает ваше имя переменной subLines (подразумевает строки текста), созданное Split() - Split без параметров будет разбито на пробелы. Следовательно, subLines содержит слова или строки? Я думаю, несмотря на название, оно содержит слова, поэтому вы можете изменить свое регулярное выражение на:

[^a-zA-Z0-9 '-]

Это оставит все апострофы в покое. Примечание. Я поместил его перед -, а не после, поэтому нет риска, что он определяет диапазон (например, A-Z) from (space) to (apostrophe) — об этом следует помнить, если вы уже пробовали это; при использовании - в классе символов и вы хотите, чтобы - был символом, а не средним диапазоном, поместите его первым (после не ^) или последним в классе

И вы можете удалить апострофы с концов ваших слов с помощью whirred.Trim('\'') - нет смысла вызывать whirred.Trim() для удаления пробелов, потому что строка уже была разделена на пробелы, поэтому в ней не останется пробелов. И Trim(), и Split() разделяются на любой символ, определенный как whitedpace методом Char.IsWhitespace(c)

person Caius Jard    schedule 28.06.2020
comment
Хорошая мысль о путанице в именах. Я изменю это. Спасибо1 - person B. Clay Shannon; 28.06.2020

Следующее может удалить апостроф по мере необходимости:

System.Text.RegularExpressions.Regex.Replace("'this isn't a' test'", "'(?=(\\s+|$))|(?<=(\\s+|^))'", "")

Выход -

это не тест

person ch_g    schedule 01.07.2020

Обновление. После повторного прочтения вопроса стало очевидно
нет необходимости во всех разбиениях и обрезках, когда все
можно сделать с помощью одного регулярное выражение, которое соответствует именно тому, что нужно.

(?:(?![^a-zA-Z0-9'-]+|(?<![a-zA-Z0-9])'|'(?![a-zA-Z0-9])).)+

см. https://regex101.com/r/fKtQ8v/1

Пример кода С#:

Regex RxWords = new Regex(@"(?:(?![^a-zA-Z0-9'-]+|(?<![a-zA-Z0-9])'|'(?![a-zA-Z0-9])).)+");
string[] doc1StrArray = { "didn't Shannons' consecrated—we, l'k'" };
int iWordsInDoc1 = 0;
string _whirred;

foreach ( string lin in doc1StrArray )
{
    Match M = RxWords.Match( lin );
    while ( M.Success )
    {
        iWordsInDoc1++;
        _whirred = M.Value;
        M = M.NextMatch();

        Console.WriteLine( "{0}", _whirred );
        //  slAllDoc1Words.Add(_whirred);
        //  if (IgnoreWord(_whirred)) continue;
        //  InsertIntoWordStatsTable(_whirred, 1, 0);
    }
}

Выход:

didn't
Shannons
consecrated
we
l'k
person Community    schedule 30.06.2020