Как извлечь текст в строку текста
У меня есть простая проблема, которую я надеюсь решить без использования VBA, но если это единственный способ ее решения, пусть будет так.
У меня есть файл с несколькими строками (всего один столбец). Каждая строка имеет данные, которые выглядят примерно так:
1 7.82E-13 > gi | 297848936 | ref | XP_00 | 4-гидроксид gi | 297338191 | gb | 23343 | randomrandom
2 5.09E-09 > gi | 168010496 | ref | xp_00 | 2-пируват
и т.д...
То, что я хочу, - это способ извлечь строку чисел, начинающуюся с "gi |" и заканчивается символом "|". Для некоторых строк это может означать целых 5 gi чисел, для других это будет только один.
Надеюсь, что вывод будет выглядеть примерно так:
297848936,297338191
168010496
и т.д...
Ответы
Ответ 1
Вот очень гибкий ответ VBA с использованием объекта regex. То, что делает эта функция, - это извлечение каждого найденного подгруппы (материал внутри скобки), разделенный любой строкой, которую вы хотите (по умолчанию - "," ). Здесь вы можете найти информацию о регулярных выражениях: http://www.regular-expressions.info/
Вы бы назвали это так, считая, что первая строка находится в A1:
=RegexExtract(A1,"gi[|](\d+)[|]")
Так как это ищет все случаи существования "gi \" за которым следует серия чисел, а затем другая "|", для первой строки в вашем вопросе это даст вам этот результат:
297848936, 297338191
Просто запустите это в столбце, и все готово!
Function RegexExtract(ByVal text As String, _
ByVal extract_what As String, _
Optional separator As String = ", ") As String
Dim allMatches As Object
Dim RE As Object
Set RE = CreateObject("vbscript.regexp")
Dim i As Long, j As Long
Dim result As String
RE.pattern = extract_what
RE.Global = True
Set allMatches = RE.Execute(text)
For i = 0 To allMatches.count - 1
For j = 0 To allMatches.Item(i).submatches.count - 1
result = result & (separator & allMatches.Item(i).submatches.Item(j))
Next
Next
If Len(result) <> 0 Then
result = Right$(result, Len(result) - Len(separator))
End If
RegexExtract = result
End Function
Ответ 2
Здесь он (если данные находятся в столбце A)
=VALUE(LEFT(RIGHT(A1,LEN(A1) - FIND("gi|",A1) - 2),
FIND("|",RIGHT(A1,LEN(A1) - FIND("gi|",A1) - 2)) -1 ))
Не самая красивая формула, но она будет работать, чтобы извлечь номер.
Я просто заметил, так как у вас есть два значения в строке с выходом, разделенным запятыми. Вам нужно будет проверить, есть ли второе совпадение, третье соответствие и т.д., Чтобы заставить его работать для нескольких номеров на ячейку.
В отношении вашего точного образца (при максимальном значении 2 значения для ячейки) будет работать следующий код:
=IF(ISNUMBER(FIND("gi|",$A1,FIND("gi|", $A1)+1)),CONCATENATE(LEFT(RIGHT($A1,LEN($A1)
- FIND("gi|",$A1) - 2),FIND("|",RIGHT($A1,LEN($A1) - FIND("gi|",$A1) - 2)) -1 ),
", ",LEFT(RIGHT($A1,LEN($A1) - FIND("gi|",$A1,FIND("gi|", $A1)+1)
- 2),FIND("|",RIGHT($A1,LEN($A1) - FIND("gi|",$A1,FIND("gi|", $A1)+1) - 2))
-1 )),LEFT(RIGHT($A1,LEN($A1) - FIND("gi|",$A1) - 2),
FIND("|",RIGHT($A1,LEN($A1) - FIND("gi|",$A1) - 2)) -1 ))
Как это для уродливого? Решение VBA может быть лучше для вас, но я оставлю это здесь для вас.
Чтобы перейти к 5 номерам, хорошо изучите шаблон и повторите процедуру вручную в формуле. IT будет длинным!
Ответ 3
Я бы, вероятно, разделил данные сначала на разделителе |
, используя мастер преобразования текста в столбцы.
В Excel 2007, который находится на вкладке Данные, Инструменты данных, а затем выберите Текст в столбцы. В качестве разделителя укажите Другое: и |
.
Из приведенных вами выборочных данных выглядит так, как только вы это сделаете, все номера будут в одинаковых столбцах, чтобы вы могли просто удалить столбцы, которые вам не нужны.
Ответ 4
Как другие ребята представили решение без VBA... Я представлю тот, который действительно использует. Теперь ваш призыв использовать его или нет.
Просто увидел, что @Issun представил решение с регулярным выражением, очень приятно! В любом случае, представит "скромное" решение вопроса, используя только "простой" VBA.
Option Explicit
Option Base 0
Sub findGi()
Dim oCell As Excel.Range
Set oCell = Sheets(1).Range("A1")
'Loops through every row until empty cell
While Not oCell.Value = ""
oCell.Offset(0, 1).Value2 = GetGi(oCell.Value)
Set oCell = oCell.Offset(1, 0)
Wend
End Sub
Private Function GetGi(ByVal sValue As String) As String
Dim sResult As String
Dim vArray As Variant
Dim vItem As Variant
Dim iCount As Integer
vArray = Split(sValue, "|")
iCount = 0
'Loops through the array...
For Each vItem In vArray
'Searches for the 'Gi' factor...
If vItem Like "*gi" And UBound(vArray) > iCount + 1 Then
'Concatenates the results...
sResult = sResult & vArray(iCount + 1) & ","
End If
iCount = iCount + 1
Next vItem
'And removes trail comma
If Len(sResult) > 0 Then
sResult = Left(sResult, Len(sResult) - 1)
End If
GetGi = sResult
End Function
Ответ 5
Кто-нибудь сможет сделать это для текстовой строки? Я хочу создать список любого слова в данном абзаце, который находится между двумя кавычками - например, в абзаце, который говорит: "Соглашение" означает x, а "Контракт" означает y. В других случаях можно использовать "Сделка".
В этом случае в ячейке рядом с ней будет указано Соглашение, Договор, Сделка
^ кавычки различны для начала и конца цитаты ("Соглашение")
Я попытался изменить этот модуль, чтобы сделать это, но ячейка показалась пустой. Любая помощь будет принята с благодарностью!