![](/img/trans.png)
[英]How do i extract a sub string which is composed of certain characters from a string in python?
[英]In python how do you extract a certain characters from a string?
我需要从该字符串中提取日期和位置。 有没有更有效的方法? 这也不太容易出错,例如前面的单词可能并不总是来自。
text = 'Join us for a guided tour of the Campus given by the
Admissions staff. The tour will take place from 3:15-4:00 PM EST
and leaves from the Admissions Office in x House. No registration required.'
length = len(text)
for x in range (length):
if text[x] == 'f' :
if text[x+1] == 'r' :
if text[x+2] == 'o':
if text[x+3] == 'm':
fprint(text[x:(x+17)])
fbreak
=从3:15-4:00 PM
要从时间范围中提取开始时间,请使用正则表达式:
(?i)\b(\d{1,2}:\d{2})(?:-\d{1,2}:\d{2})?(\s*[pa]m)\b
详细资料 :
(?i)
-不区分大小写的匹配打开 \\b
前导词边界 (\\d{1,2}:\\d{2})
-组1捕获1或2位数字, :
和2位数字 (?:-\\d{1,2}:\\d{2})?
-匹配以下情况的1或0的可选非捕获组:
-
连字符 \\d{1,2}
-1或2位数字 :
-冒号 \\d{2}
-2位数字 (\\s*[pa]m)
-第2组捕获以下序列:
\\s*
-0+空格 [pa]
p
或a
(或P
或A
) m
- m
或M
\\b
尾部单词边界。 参见Python演示 :
import re
rx = r"(?i)\b(\d{1,2}:\d{2})(?:-\d{1,2}:\d{2})?(\s*[pa]m)\b"
s = "Join us for a guided tour of the Campus given by the \nAdmissions staff. The tour will take place from 3:15-4:00 PM EST or from 7:30 AM EST \nand leaves from the Admissions Office in x House. No registration required.' "
matches = ["{}{}".format(x.group(1),x.group(2)) for x in re.finditer(rx, s)]
print(matches)
由于结果分为两个单独的组,因此我们需要迭代所有匹配项并合并两个组的值。
您可以使用以下正则表达式:
r"from [^A-Za-z]+"
哪个会在文本中查找以“ from”开头且后没有任何字母(AM或PM除外)的地方。 在您提供的文本上返回
从3:15-4:00 PM
您可以通过以下方式使用它:
import re print(re.search("from [^A-Za-z]+(?:AM|PM)", text))
您不仅限于使用正则表达式来解析字符串内容。
除了使用正则表达式,您还可以使用下面介绍的解析技术。 它类似于在编译器中使用的技术。
首先,您可以看一下此示例。 它只会在文本中找到时间。
TEXT = 'Join us for a guided tour of the Campus given by the Admissions staff. The tour will take place ' \
'from 3:15-4:00 PM EST and leaves from the Admissions Office in AA A AAA House. No registration required.\n' \
'The tour will take place from 7:30 AM UTC and leaves from the Admissions Office in B BBB House.\n' \
'The tour will take place 17:30 UTC and leaves from the Admissions Office in C CCC C House.\n' \
'The tour will take place 9:30-11:00 AM and leaves from the Admissions Office in DDD House.\n' \
'The tour will take place 15:00-16:25 and leaves from the Admissions Office in EE EE House.\n' \
'No registration required. '
TIME_SEPARATORS = ':-'
time_text_start = None
time_text_end = None
time_text = ''
index = 0
for char in TEXT:
if time_text_start is None:
if char.isdigit():
time_text_start = index
if (time_text_start is not None) and (time_text_end is None):
if (not char.isdigit()) and (not char.isspace()) and (char not in TIME_SEPARATORS):
time_text_end = index
time_text = TEXT[time_text_start: time_text_end].strip()
print(time_text)
# Now we will clear our variables to be able to find next time_text data in the text
time_text_start = None
time_text_end = None
time_text = ''
index += 1
该代码将在下面打印:
3:15-4:00
7:30
17:30
9:30-11:00
15:00-16:25
现在,您可以查看真实的代码。 它将找到您需要的所有数据:时间,时间段,时间标准和位置。
文本中的位置必须在时间之后并且在“在”和“家”之间。
要添加其他搜索条件,您可以修改EventsDataFinder
类的def find(self, text_to_process)
方法。
要更改格式(例如,返回仅结束时间的完整时间),可以修改EventsDataFinder
类的def _prepare_event_data(time_text, time_period, time_standard, event_place)
方法。
PS:我知道对于初学者来说这些课程可能很难理解。 因此,我尝试使此代码尽可能简单。 但是如果没有类,代码将很难理解。 所以有几个。
class TextUnit:
text = ''
start = None
end = None
absent = False
def fill_from_text(self, text):
self.text = text[self.start: self.end].strip()
def clear(self):
self.text = ''
self.start = None
self.end = None
self.absent = False
class EventsDataFinder:
time_standards = {
'est',
'utc',
'dst',
'edt'
}
time_standard_text_len = 3
period = {
'am',
'pm'
}
period_text_len = 2
time_separators = ':-'
event_place_start_indicator = ' in '
event_place_end_indicator = ' house'
fake_text_end = '.'
def find(self, text_to_process):
'''
This method will parse given text and will return list of tuples. Each tuple will contain time of the event
in the desired format and location of the event.
:param text_to_process: text to parse
:return: list of tuples. For example [('3:15 PM EST', 'AA A AAA'), ('7:30 AM UTC', 'B BBB')]
'''
text = text_to_process.replace('\n', '')
text += self.fake_text_end
time_text = TextUnit()
time_period = TextUnit()
time_standard = TextUnit()
event_place = TextUnit()
result_events = list()
index = -1
for char in text:
index += 1
# Time text
if time_text.start is None:
if char.isdigit():
time_text.start = index
if (time_text.start is not None) and (time_text.end is None):
if (not char.isdigit()) and (not char.isspace()) and (char not in self.time_separators):
time_text.end = index
time_text.fill_from_text(text)
# Time period
# If time_text is already found:
if (time_text.end is not None) and \
(time_period.end is None) and (not time_period.absent) and \
(not char.isspace()):
potential_period = text[index: index + self.period_text_len].lower()
if potential_period in self.period:
time_period.start = index
time_period.end = index + self.period_text_len
time_period.fill_from_text(text)
else:
time_period.absent = True
# Time standard
# If time_period is already found or does not exist:
if (time_period.absent or ((time_period.end is not None) and (index >= time_period.end))) and \
(time_standard.end is None) and (not time_standard.absent) and \
(not char.isspace()):
potential_standard = text[index: index + self.time_standard_text_len].lower()
if potential_standard in self.time_standards:
time_standard.start = index
time_standard.end = index + self.time_standard_text_len
time_standard.fill_from_text(text)
else:
time_standard.absent = True
# Event place
# If time_standard is already found or does not exist:
if (time_standard.absent or ((time_standard.end is not None) and (index >= time_standard.end))) and \
(event_place.end is None) and (not event_place.absent):
if self.event_place_end_indicator.startswith(char.lower()):
potential_event_place = text[index: index + len(self.event_place_end_indicator)].lower()
if potential_event_place == self.event_place_end_indicator:
event_place.end = index
potential_event_place_start = text.rfind(self.event_place_start_indicator,
time_text.end,
event_place.end)
if potential_event_place_start > 0:
event_place.start = potential_event_place_start + len(self.event_place_start_indicator)
event_place.fill_from_text(text)
else:
event_place.absent = True
# Saving result and clearing temporary data holders
# If event_place is already found or does not exist:
if event_place.absent or (event_place.end is not None):
result_events.append(self._prepare_event_data(time_text,
time_period,
time_standard,
event_place))
time_text.clear()
time_period.clear()
time_standard.clear()
event_place.clear()
# This code will save data of the last incomplete event (all that was found). If it exists of course.
if (time_text.end is not None) and (event_place.end is None):
result_events.append(self._prepare_event_data(time_text,
time_period,
time_standard,
event_place))
return result_events
@staticmethod
def _prepare_event_data(time_text, time_period, time_standard, event_place):
'''
This method will prepare found data to be saved in a desired format
:param time_text: text of time
:param time_period: text of period
:param time_standard: text of time standard
:param event_place: location of the event
:return: will return ready to save tuple. For example ('3:15 PM EST', 'AA A AAA')
'''
event_time = time_text.text # '3:15-4:00'
split_time = event_time.split('-') # ['3:15', '4:00']
if 1 < len(split_time):
# If it was, for example, '3:15-4:00 PM EST' in the text
start_time = split_time[0].strip() # '3:15'
end_time = split_time[1].strip() # '4:00'
else:
# If it was, for example, '3:15 PM EST' in the text
start_time = event_time # '3:15'
end_time = '' # ''
period = time_period.text.upper() # 'PM'
standard = time_standard.text.upper() # 'EST'
event_place = event_place.text #
# Removing empty time fields (for example if there is no period or time standard in the text)
time_data_separated = [start_time, period, standard]
new_time_data_separated = list()
for item in time_data_separated:
if item:
new_time_data_separated.append(item)
time_data_separated = new_time_data_separated
event_time_interval = ' '.join(time_data_separated)
result = (event_time_interval, event_place)
return result
TEXT = 'Join us for a guided tour of the Campus given by the Admissions staff. The tour will take place ' \
'from 3:15-4:00 PM EST and leaves from the Admissions Office in AA A AAA House. No registration required.\n' \
'The tour will take place from 7:30 AM UTC and leaves from the Admissions Office in B BBB House.\n' \
'The tour will take place 17:30 UTC and leaves from the Admissions Office in C CCC C House.\n' \
'The tour will take place 9:30-11:00 AM and leaves from the Admissions Office in DDD House.\n' \
'The tour will take place 15:00-16:25 and leaves from the Admissions Office in EE EE House.\n' \
'No registration required. '
edf = EventsDataFinder()
print(edf.find(TEXT))
假设我们有下一段文字:
加入我们,由招生人员进行校园导览游。 游览时间为美国东部标准时间下午3:15-4:00 ,出发地点为AA AAA House的招生办公室。
该巡回赛将于世界标准时间上午7:30开始,并从B BBB House的招生办公室出发。
游览将在世界标准时间17:30进行,并从C CCC C House的招生办公室出发。
游览将在9:30-11:00 AM进行,并从DDD House的招生办公室出发。
游览将在15:00-16:25进行,并离开EE EE House的招生办公室。
无需注册。
因此,此代码将打印:
[('3:15 PM EST', 'AA A AAA'), ('7:30 AM UTC', 'B BBB'), ('17:30 UTC', 'C CCC C'), ('9:30 AM', 'DDD'), ('15:00', 'EE EE')]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.